root/drivers/misc/vmw_vmci/vmci_handle_array.c

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

DEFINITIONS

This source file includes following definitions.
  1. handle_arr_calc_size
  2. vmci_handle_arr_create
  3. vmci_handle_arr_destroy
  4. vmci_handle_arr_append_entry
  5. vmci_handle_arr_remove_entry
  6. vmci_handle_arr_remove_tail
  7. vmci_handle_arr_get_entry
  8. vmci_handle_arr_has_entry
  9. vmci_handle_arr_get_handles

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * VMware VMCI Driver
   4  *
   5  * Copyright (C) 2012 VMware, Inc. All rights reserved.
   6  */
   7 
   8 #include <linux/slab.h>
   9 #include "vmci_handle_array.h"
  10 
  11 static size_t handle_arr_calc_size(u32 capacity)
  12 {
  13         return VMCI_HANDLE_ARRAY_HEADER_SIZE +
  14             capacity * sizeof(struct vmci_handle);
  15 }
  16 
  17 struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity)
  18 {
  19         struct vmci_handle_arr *array;
  20 
  21         if (max_capacity == 0 || capacity > max_capacity)
  22                 return NULL;
  23 
  24         if (capacity == 0)
  25                 capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY,
  26                                max_capacity);
  27 
  28         array = kmalloc(handle_arr_calc_size(capacity), GFP_ATOMIC);
  29         if (!array)
  30                 return NULL;
  31 
  32         array->capacity = capacity;
  33         array->max_capacity = max_capacity;
  34         array->size = 0;
  35 
  36         return array;
  37 }
  38 
  39 void vmci_handle_arr_destroy(struct vmci_handle_arr *array)
  40 {
  41         kfree(array);
  42 }
  43 
  44 int vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr,
  45                                  struct vmci_handle handle)
  46 {
  47         struct vmci_handle_arr *array = *array_ptr;
  48 
  49         if (unlikely(array->size >= array->capacity)) {
  50                 /* reallocate. */
  51                 struct vmci_handle_arr *new_array;
  52                 u32 capacity_bump = min(array->max_capacity - array->capacity,
  53                                         array->capacity);
  54                 size_t new_size = handle_arr_calc_size(array->capacity +
  55                                                        capacity_bump);
  56 
  57                 if (array->size >= array->max_capacity)
  58                         return VMCI_ERROR_NO_MEM;
  59 
  60                 new_array = krealloc(array, new_size, GFP_ATOMIC);
  61                 if (!new_array)
  62                         return VMCI_ERROR_NO_MEM;
  63 
  64                 new_array->capacity += capacity_bump;
  65                 *array_ptr = array = new_array;
  66         }
  67 
  68         array->entries[array->size] = handle;
  69         array->size++;
  70 
  71         return VMCI_SUCCESS;
  72 }
  73 
  74 /*
  75  * Handle that was removed, VMCI_INVALID_HANDLE if entry not found.
  76  */
  77 struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array,
  78                                                 struct vmci_handle entry_handle)
  79 {
  80         struct vmci_handle handle = VMCI_INVALID_HANDLE;
  81         u32 i;
  82 
  83         for (i = 0; i < array->size; i++) {
  84                 if (vmci_handle_is_equal(array->entries[i], entry_handle)) {
  85                         handle = array->entries[i];
  86                         array->size--;
  87                         array->entries[i] = array->entries[array->size];
  88                         array->entries[array->size] = VMCI_INVALID_HANDLE;
  89                         break;
  90                 }
  91         }
  92 
  93         return handle;
  94 }
  95 
  96 /*
  97  * Handle that was removed, VMCI_INVALID_HANDLE if array was empty.
  98  */
  99 struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array)
 100 {
 101         struct vmci_handle handle = VMCI_INVALID_HANDLE;
 102 
 103         if (array->size) {
 104                 array->size--;
 105                 handle = array->entries[array->size];
 106                 array->entries[array->size] = VMCI_INVALID_HANDLE;
 107         }
 108 
 109         return handle;
 110 }
 111 
 112 /*
 113  * Handle at given index, VMCI_INVALID_HANDLE if invalid index.
 114  */
 115 struct vmci_handle
 116 vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, u32 index)
 117 {
 118         if (unlikely(index >= array->size))
 119                 return VMCI_INVALID_HANDLE;
 120 
 121         return array->entries[index];
 122 }
 123 
 124 bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array,
 125                                struct vmci_handle entry_handle)
 126 {
 127         u32 i;
 128 
 129         for (i = 0; i < array->size; i++)
 130                 if (vmci_handle_is_equal(array->entries[i], entry_handle))
 131                         return true;
 132 
 133         return false;
 134 }
 135 
 136 /*
 137  * NULL if the array is empty. Otherwise, a pointer to the array
 138  * of VMCI handles in the handle array.
 139  */
 140 struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array)
 141 {
 142         if (array->size)
 143                 return array->entries;
 144 
 145         return NULL;
 146 }

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