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