Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

VMCI: handle array implementation.

VMCI handle code adds support for dynamic arrays that will grow if they need to.

Signed-off-by: George Zhang <georgezhang@vmware.com>
Acked-by: Andy king <acking@vmware.com>
Acked-by: Dmitry Torokhov <dtor@vmware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

George Zhang and committed by
Greg Kroah-Hartman
b484b26c 1d990201

+194
+142
drivers/misc/vmw_vmci/vmci_handle_array.c
··· 1 + /* 2 + * VMware VMCI Driver 3 + * 4 + * Copyright (C) 2012 VMware, Inc. All rights reserved. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the 8 + * Free Software Foundation version 2 and no later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, but 11 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 + * for more details. 14 + */ 15 + 16 + #include <linux/slab.h> 17 + #include "vmci_handle_array.h" 18 + 19 + static size_t handle_arr_calc_size(size_t capacity) 20 + { 21 + return sizeof(struct vmci_handle_arr) + 22 + capacity * sizeof(struct vmci_handle); 23 + } 24 + 25 + struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity) 26 + { 27 + struct vmci_handle_arr *array; 28 + 29 + if (capacity == 0) 30 + capacity = VMCI_HANDLE_ARRAY_DEFAULT_SIZE; 31 + 32 + array = kmalloc(handle_arr_calc_size(capacity), GFP_ATOMIC); 33 + if (!array) 34 + return NULL; 35 + 36 + array->capacity = capacity; 37 + array->size = 0; 38 + 39 + return array; 40 + } 41 + 42 + void vmci_handle_arr_destroy(struct vmci_handle_arr *array) 43 + { 44 + kfree(array); 45 + } 46 + 47 + void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, 48 + struct vmci_handle handle) 49 + { 50 + struct vmci_handle_arr *array = *array_ptr; 51 + 52 + if (unlikely(array->size >= array->capacity)) { 53 + /* reallocate. */ 54 + struct vmci_handle_arr *new_array; 55 + size_t new_capacity = array->capacity * VMCI_ARR_CAP_MULT; 56 + size_t new_size = handle_arr_calc_size(new_capacity); 57 + 58 + new_array = krealloc(array, new_size, GFP_ATOMIC); 59 + if (!new_array) 60 + return; 61 + 62 + new_array->capacity = new_capacity; 63 + *array_ptr = array = new_array; 64 + } 65 + 66 + array->entries[array->size] = handle; 67 + array->size++; 68 + } 69 + 70 + /* 71 + * Handle that was removed, VMCI_INVALID_HANDLE if entry not found. 72 + */ 73 + struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array, 74 + struct vmci_handle entry_handle) 75 + { 76 + struct vmci_handle handle = VMCI_INVALID_HANDLE; 77 + size_t i; 78 + 79 + for (i = 0; i < array->size; i++) { 80 + if (vmci_handle_is_equal(array->entries[i], entry_handle)) { 81 + handle = array->entries[i]; 82 + array->size--; 83 + array->entries[i] = array->entries[array->size]; 84 + array->entries[array->size] = VMCI_INVALID_HANDLE; 85 + break; 86 + } 87 + } 88 + 89 + return handle; 90 + } 91 + 92 + /* 93 + * Handle that was removed, VMCI_INVALID_HANDLE if array was empty. 94 + */ 95 + struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array) 96 + { 97 + struct vmci_handle handle = VMCI_INVALID_HANDLE; 98 + 99 + if (array->size) { 100 + array->size--; 101 + handle = array->entries[array->size]; 102 + array->entries[array->size] = VMCI_INVALID_HANDLE; 103 + } 104 + 105 + return handle; 106 + } 107 + 108 + /* 109 + * Handle at given index, VMCI_INVALID_HANDLE if invalid index. 110 + */ 111 + struct vmci_handle 112 + vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index) 113 + { 114 + if (unlikely(index >= array->size)) 115 + return VMCI_INVALID_HANDLE; 116 + 117 + return array->entries[index]; 118 + } 119 + 120 + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, 121 + struct vmci_handle entry_handle) 122 + { 123 + size_t i; 124 + 125 + for (i = 0; i < array->size; i++) 126 + if (vmci_handle_is_equal(array->entries[i], entry_handle)) 127 + return true; 128 + 129 + return false; 130 + } 131 + 132 + /* 133 + * NULL if the array is empty. Otherwise, a pointer to the array 134 + * of VMCI handles in the handle array. 135 + */ 136 + struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array) 137 + { 138 + if (array->size) 139 + return array->entries; 140 + 141 + return NULL; 142 + }
+52
drivers/misc/vmw_vmci/vmci_handle_array.h
··· 1 + /* 2 + * VMware VMCI Driver 3 + * 4 + * Copyright (C) 2012 VMware, Inc. All rights reserved. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the 8 + * Free Software Foundation version 2 and no later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, but 11 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 + * for more details. 14 + */ 15 + 16 + #ifndef _VMCI_HANDLE_ARRAY_H_ 17 + #define _VMCI_HANDLE_ARRAY_H_ 18 + 19 + #include <linux/vmw_vmci_defs.h> 20 + #include <linux/types.h> 21 + 22 + #define VMCI_HANDLE_ARRAY_DEFAULT_SIZE 4 23 + #define VMCI_ARR_CAP_MULT 2 /* Array capacity multiplier */ 24 + 25 + struct vmci_handle_arr { 26 + size_t capacity; 27 + size_t size; 28 + struct vmci_handle entries[]; 29 + }; 30 + 31 + struct vmci_handle_arr *vmci_handle_arr_create(size_t capacity); 32 + void vmci_handle_arr_destroy(struct vmci_handle_arr *array); 33 + void vmci_handle_arr_append_entry(struct vmci_handle_arr **array_ptr, 34 + struct vmci_handle handle); 35 + struct vmci_handle vmci_handle_arr_remove_entry(struct vmci_handle_arr *array, 36 + struct vmci_handle 37 + entry_handle); 38 + struct vmci_handle vmci_handle_arr_remove_tail(struct vmci_handle_arr *array); 39 + struct vmci_handle 40 + vmci_handle_arr_get_entry(const struct vmci_handle_arr *array, size_t index); 41 + bool vmci_handle_arr_has_entry(const struct vmci_handle_arr *array, 42 + struct vmci_handle entry_handle); 43 + struct vmci_handle *vmci_handle_arr_get_handles(struct vmci_handle_arr *array); 44 + 45 + static inline size_t vmci_handle_arr_get_size( 46 + const struct vmci_handle_arr *array) 47 + { 48 + return array->size; 49 + } 50 + 51 + 52 + #endif /* _VMCI_HANDLE_ARRAY_H_ */