root/drivers/misc/ocxl/pasid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dump_list
  2. range_alloc
  3. range_free
  4. ocxl_pasid_afu_alloc
  5. ocxl_pasid_afu_free
  6. ocxl_actag_afu_alloc
  7. ocxl_actag_afu_free

   1 // SPDX-License-Identifier: GPL-2.0+
   2 // Copyright 2017 IBM Corp.
   3 #include "ocxl_internal.h"
   4 
   5 
   6 struct id_range {
   7         struct list_head list;
   8         u32 start;
   9         u32 end;
  10 };
  11 
  12 #ifdef DEBUG
  13 static void dump_list(struct list_head *head, char *type_str)
  14 {
  15         struct id_range *cur;
  16 
  17         pr_debug("%s ranges allocated:\n", type_str);
  18         list_for_each_entry(cur, head, list) {
  19                 pr_debug("Range %d->%d\n", cur->start, cur->end);
  20         }
  21 }
  22 #endif
  23 
  24 static int range_alloc(struct list_head *head, u32 size, int max_id,
  25                 char *type_str)
  26 {
  27         struct list_head *pos;
  28         struct id_range *cur, *new;
  29         int rc, last_end;
  30 
  31         new = kmalloc(sizeof(struct id_range), GFP_KERNEL);
  32         if (!new)
  33                 return -ENOMEM;
  34 
  35         pos = head;
  36         last_end = -1;
  37         list_for_each_entry(cur, head, list) {
  38                 if ((cur->start - last_end) > size)
  39                         break;
  40                 last_end = cur->end;
  41                 pos = &cur->list;
  42         }
  43 
  44         new->start = last_end + 1;
  45         new->end = new->start + size - 1;
  46 
  47         if (new->end > max_id) {
  48                 kfree(new);
  49                 rc = -ENOSPC;
  50         } else {
  51                 list_add(&new->list, pos);
  52                 rc = new->start;
  53         }
  54 
  55 #ifdef DEBUG
  56         dump_list(head, type_str);
  57 #endif
  58         return rc;
  59 }
  60 
  61 static void range_free(struct list_head *head, u32 start, u32 size,
  62                 char *type_str)
  63 {
  64         bool found = false;
  65         struct id_range *cur, *tmp;
  66 
  67         list_for_each_entry_safe(cur, tmp, head, list) {
  68                 if (cur->start == start && cur->end == (start + size - 1)) {
  69                         found = true;
  70                         list_del(&cur->list);
  71                         kfree(cur);
  72                         break;
  73                 }
  74         }
  75         WARN_ON(!found);
  76 #ifdef DEBUG
  77         dump_list(head, type_str);
  78 #endif
  79 }
  80 
  81 int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size)
  82 {
  83         int max_pasid;
  84 
  85         if (fn->config.max_pasid_log < 0)
  86                 return -ENOSPC;
  87         max_pasid = 1 << fn->config.max_pasid_log;
  88         return range_alloc(&fn->pasid_list, size, max_pasid, "afu pasid");
  89 }
  90 
  91 void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size)
  92 {
  93         return range_free(&fn->pasid_list, start, size, "afu pasid");
  94 }
  95 
  96 int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size)
  97 {
  98         int max_actag;
  99 
 100         max_actag = fn->actag_enabled;
 101         return range_alloc(&fn->actag_list, size, max_actag, "afu actag");
 102 }
 103 
 104 void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size)
 105 {
 106         return range_free(&fn->actag_list, start, size, "afu actag");
 107 }

/* [<][>][^][v][top][bottom][index][help] */