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