1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2019 Mellanox Technologies, Ltd 3 */ 4 5 #ifndef RTE_PMD_MLX5_COMMON_UTILS_H_ 6 #define RTE_PMD_MLX5_COMMON_UTILS_H_ 7 8 #include <rte_compat.h> 9 #include <rte_rwlock.h> 10 11 #include "mlx5_common.h" 12 13 /************************ mlx5 list *****************************/ 14 15 /** Maximum size of string for naming. */ 16 #define MLX5_NAME_SIZE 32 17 /** Maximum size of list. */ 18 #define MLX5_LIST_MAX (RTE_MAX_LCORE + 2) 19 /** Global list index. */ 20 #define MLX5_LIST_GLOBAL ((MLX5_LIST_MAX) - 1) 21 /** None rte core list index. */ 22 #define MLX5_LIST_NLCORE ((MLX5_LIST_MAX) - 2) 23 24 struct mlx5_list; 25 26 /** 27 * Structure of the entry in the mlx5 list, user should define its own struct 28 * that contains this in order to store the data. 29 */ 30 struct __rte_packed_begin mlx5_list_entry { 31 LIST_ENTRY(mlx5_list_entry) next; /* Entry pointers in the list. */ 32 alignas(8) RTE_ATOMIC(uint32_t) ref_cnt; /* 0 means, entry is invalid. */ 33 uint32_t lcore_idx; 34 union { 35 struct mlx5_list_entry *gentry; 36 uint32_t bucket_idx; 37 }; 38 } __rte_packed_end; 39 40 struct __rte_cache_aligned mlx5_list_cache { 41 LIST_HEAD(mlx5_list_head, mlx5_list_entry) h; 42 RTE_ATOMIC(uint32_t) inv_cnt; /* Invalid entries counter. */ 43 }; 44 45 /** 46 * Type of callback function for entry removal. 47 * 48 * @param tool_ctx 49 * The tool instance user context. 50 * @param entry 51 * The entry in the list. 52 */ 53 typedef void (*mlx5_list_remove_cb)(void *tool_ctx, 54 struct mlx5_list_entry *entry); 55 56 /** 57 * Type of function for user defined matching. 58 * 59 * @param tool_ctx 60 * The tool instance context. 61 * @param entry 62 * The entry in the list. 63 * @param ctx 64 * The pointer to new entry context. 65 * 66 * @return 67 * 0 if matching, non-zero number otherwise. 68 */ 69 typedef int (*mlx5_list_match_cb)(void *tool_ctx, 70 struct mlx5_list_entry *entry, void *ctx); 71 72 typedef struct mlx5_list_entry *(*mlx5_list_clone_cb)(void *tool_ctx, 73 struct mlx5_list_entry *entry, void *ctx); 74 75 typedef void (*mlx5_list_clone_free_cb)(void *tool_ctx, 76 struct mlx5_list_entry *entry); 77 78 /** 79 * Type of function for user defined mlx5 list entry creation. 80 * 81 * @param tool_ctx 82 * The mlx5 tool instance context. 83 * @param ctx 84 * The pointer to new entry context. 85 * 86 * @return 87 * Pointer of entry on success, NULL otherwise. 88 */ 89 typedef struct mlx5_list_entry *(*mlx5_list_create_cb)(void *tool_ctx, 90 void *ctx); 91 92 /** 93 * Linked mlx5 list constant object. 94 */ 95 struct mlx5_list_const { 96 char name[MLX5_NAME_SIZE]; /**< Name of the mlx5 list. */ 97 void *ctx; /* user objects target to callback. */ 98 bool lcores_share; /* Whether to share objects between the lcores. */ 99 rte_spinlock_t lcore_lock; /* Lock for non-lcore list. */ 100 mlx5_list_create_cb cb_create; /**< entry create callback. */ 101 mlx5_list_match_cb cb_match; /**< entry match callback. */ 102 mlx5_list_remove_cb cb_remove; /**< entry remove callback. */ 103 mlx5_list_clone_cb cb_clone; /**< entry clone callback. */ 104 mlx5_list_clone_free_cb cb_clone_free; 105 /**< entry clone free callback. */ 106 }; 107 108 /** 109 * Linked mlx5 list inconstant data. 110 */ 111 struct mlx5_list_inconst { 112 rte_rwlock_t lock; /* read/write lock. */ 113 volatile uint32_t gen_cnt; /* List modification may update it. */ 114 volatile RTE_ATOMIC(uint32_t) count; /* number of entries in list. */ 115 struct mlx5_list_cache *cache[MLX5_LIST_MAX]; 116 /* Lcore cache, last index is the global cache. */ 117 }; 118 119 /** 120 * Linked mlx5 list structure. 121 * 122 * Entry in mlx5 list could be reused if entry already exists, 123 * reference count will increase and the existing entry returns. 124 * 125 * When destroy an entry from list, decrease reference count and only 126 * destroy when no further reference. 127 * 128 * Linked list is designed for limited number of entries, 129 * read mostly, less modification. 130 * 131 * For huge amount of entries, please consider hash list. 132 * 133 */ 134 struct __rte_aligned(16) mlx5_list { 135 struct mlx5_list_const l_const; 136 struct mlx5_list_inconst l_inconst; 137 }; 138 139 /** 140 * Create a mlx5 list. 141 * 142 * For actions in SW-steering is only memory and can be allowed 143 * to create duplicate objects, the lists don't need to check if 144 * there are existing same objects in other sub local lists, 145 * search the object only in local list will be more efficient. 146 * 147 * @param list 148 * Pointer to the hast list table. 149 * @param name 150 * Name of the mlx5 list. 151 * @param ctx 152 * Pointer to the list context data. 153 * @param lcores_share 154 * Whether to share objects between the lcores. 155 * @param cb_create 156 * Callback function for entry create. 157 * @param cb_match 158 * Callback function for entry match. 159 * @param cb_remove 160 * Callback function for entry remove. 161 * @return 162 * List pointer on success, otherwise NULL. 163 */ 164 __rte_internal 165 struct mlx5_list *mlx5_list_create(const char *name, void *ctx, 166 bool lcores_share, 167 mlx5_list_create_cb cb_create, 168 mlx5_list_match_cb cb_match, 169 mlx5_list_remove_cb cb_remove, 170 mlx5_list_clone_cb cb_clone, 171 mlx5_list_clone_free_cb cb_clone_free); 172 173 /** 174 * Search an entry matching the key. 175 * 176 * Result returned might be destroyed by other thread, must use 177 * this function only in main thread. 178 * 179 * @param list 180 * Pointer to the mlx5 list. 181 * @param ctx 182 * Common context parameter used by entry callback function. 183 * 184 * @return 185 * Pointer of the list entry if found, NULL otherwise. 186 */ 187 __rte_internal 188 struct mlx5_list_entry *mlx5_list_lookup(struct mlx5_list *list, 189 void *ctx); 190 191 /** 192 * Reuse or create an entry to the mlx5 list. 193 * 194 * @param list 195 * Pointer to the hast list table. 196 * @param ctx 197 * Common context parameter used by callback function. 198 * 199 * @return 200 * registered entry on success, NULL otherwise 201 */ 202 __rte_internal 203 struct mlx5_list_entry *mlx5_list_register(struct mlx5_list *list, 204 void *ctx); 205 206 /** 207 * Remove an entry from the mlx5 list. 208 * 209 * User should guarantee the validity of the entry. 210 * 211 * @param list 212 * Pointer to the hast list. 213 * @param entry 214 * Entry to be removed from the mlx5 list table. 215 * @return 216 * 0 on entry removed, 1 on entry still referenced. 217 */ 218 __rte_internal 219 int mlx5_list_unregister(struct mlx5_list *list, 220 struct mlx5_list_entry *entry); 221 222 /** 223 * Destroy the mlx5 list. 224 * 225 * @param list 226 * Pointer to the mlx5 list. 227 */ 228 __rte_internal 229 void mlx5_list_destroy(struct mlx5_list *list); 230 231 /** 232 * Get entry number from the mlx5 list. 233 * 234 * @param list 235 * Pointer to the hast list. 236 * @return 237 * mlx5 list entry number. 238 */ 239 __rte_internal 240 uint32_t 241 mlx5_list_get_entry_num(struct mlx5_list *list); 242 243 /********************* Hash List **********************/ 244 245 /* Hash list bucket. */ 246 struct __rte_cache_aligned mlx5_hlist_bucket { 247 struct mlx5_list_inconst l; 248 }; 249 250 /** 251 * Hash list table structure 252 * 253 * The hash list bucket using the mlx5_list object for managing. 254 */ 255 struct mlx5_hlist { 256 uint32_t mask; /* A mask for the bucket index range. */ 257 uint8_t flags; 258 bool direct_key; /* Whether to use the key directly as hash index. */ 259 struct mlx5_list_const l_const; /* List constant data. */ 260 alignas(RTE_CACHE_LINE_SIZE) struct mlx5_hlist_bucket buckets[]; 261 }; 262 263 /** 264 * Create a hash list table, the user can specify the list heads array size 265 * of the table, now the size should be a power of 2 in order to get better 266 * distribution for the entries. Each entry is a part of the whole data element 267 * and the caller should be responsible for the data element's allocation and 268 * cleanup / free. Key of each entry will be calculated with CRC in order to 269 * generate a little fairer distribution. 270 * 271 * @param name 272 * Name of the hash list(optional). 273 * @param size 274 * Heads array size of the hash list. 275 * @param entry_size 276 * Entry size to allocate if cb_create not specified. 277 * @param direct key 278 * Whether to use the key directly as hash index. 279 * @param lcores_share 280 * Whether to share objects between the lcores. 281 * @param ctx 282 * The hlist instance context. 283 * @param cb_create 284 * Callback function for entry create. 285 * @param cb_match 286 * Callback function for entry match. 287 * @param cb_remove 288 * Callback function for entry remove. 289 * @param cb_clone 290 * Callback function for entry clone. 291 * @param cb_clone_free 292 * Callback function for entry clone free. 293 * @return 294 * Pointer of the hash list table created, NULL on failure. 295 */ 296 __rte_internal 297 struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size, 298 bool direct_key, bool lcores_share, 299 void *ctx, mlx5_list_create_cb cb_create, 300 mlx5_list_match_cb cb_match, 301 mlx5_list_remove_cb cb_remove, 302 mlx5_list_clone_cb cb_clone, 303 mlx5_list_clone_free_cb cb_clone_free); 304 305 /** 306 * Search an entry matching the key. 307 * 308 * Result returned might be destroyed by other thread, must use 309 * this function only in main thread. 310 * 311 * @param h 312 * Pointer to the hast list table. 313 * @param key 314 * Key for the searching entry. 315 * @param ctx 316 * Common context parameter used by entry callback function. 317 * 318 * @return 319 * Pointer of the hlist entry if found, NULL otherwise. 320 */ 321 __rte_internal 322 struct mlx5_list_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, 323 void *ctx); 324 325 /** 326 * Insert an entry to the hash list table, the entry is only part of whole data 327 * element and a 64B key is used for matching. User should construct the key or 328 * give a calculated hash signature and guarantee there is no collision. 329 * 330 * @param h 331 * Pointer to the hast list table. 332 * @param entry 333 * Entry to be inserted into the hash list table. 334 * @param ctx 335 * Common context parameter used by callback function. 336 * 337 * @return 338 * registered entry on success, NULL otherwise 339 */ 340 __rte_internal 341 struct mlx5_list_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key, 342 void *ctx); 343 344 /** 345 * Remove an entry from the hash list table. User should guarantee the validity 346 * of the entry. 347 * 348 * @param h 349 * Pointer to the hast list table. (not used) 350 * @param entry 351 * Entry to be removed from the hash list table. 352 * @return 353 * 0 on entry removed, 1 on entry still referenced. 354 */ 355 __rte_internal 356 int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_list_entry *entry); 357 358 /** 359 * Destroy the hash list table, all the entries already inserted into the lists 360 * will be handled by the callback function provided by the user (including 361 * free if needed) before the table is freed. 362 * 363 * @param h 364 * Pointer to the hast list table. 365 */ 366 __rte_internal 367 void mlx5_hlist_destroy(struct mlx5_hlist *h); 368 369 #endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */ 370