17b4f1e6bSMatan Azrad /* SPDX-License-Identifier: BSD-3-Clause 27b4f1e6bSMatan Azrad * Copyright 2019 Mellanox Technologies, Ltd 37b4f1e6bSMatan Azrad */ 47b4f1e6bSMatan Azrad 57b4f1e6bSMatan Azrad #ifndef RTE_PMD_MLX5_COMMON_UTILS_H_ 67b4f1e6bSMatan Azrad #define RTE_PMD_MLX5_COMMON_UTILS_H_ 77b4f1e6bSMatan Azrad 87b4f1e6bSMatan Azrad #include "mlx5_common.h" 97b4f1e6bSMatan Azrad 109c373c52SSuanming Mou /************************ mlx5 list *****************************/ 119c373c52SSuanming Mou 129c373c52SSuanming Mou /** Maximum size of string for naming. */ 139c373c52SSuanming Mou #define MLX5_NAME_SIZE 32 149c373c52SSuanming Mou 159c373c52SSuanming Mou struct mlx5_list; 169c373c52SSuanming Mou 179c373c52SSuanming Mou /** 189c373c52SSuanming Mou * Structure of the entry in the mlx5 list, user should define its own struct 199c373c52SSuanming Mou * that contains this in order to store the data. 209c373c52SSuanming Mou */ 219c373c52SSuanming Mou struct mlx5_list_entry { 229c373c52SSuanming Mou LIST_ENTRY(mlx5_list_entry) next; /* Entry pointers in the list. */ 23961b6774SMatan Azrad uint32_t ref_cnt __rte_aligned(8); /* 0 means, entry is invalid. */ 249c373c52SSuanming Mou uint32_t lcore_idx; 25961b6774SMatan Azrad union { 269c373c52SSuanming Mou struct mlx5_list_entry *gentry; 27961b6774SMatan Azrad uint32_t bucket_idx; 289c373c52SSuanming Mou }; 29961b6774SMatan Azrad } __rte_packed; 309c373c52SSuanming Mou 319c373c52SSuanming Mou struct mlx5_list_cache { 329c373c52SSuanming Mou LIST_HEAD(mlx5_list_head, mlx5_list_entry) h; 339c373c52SSuanming Mou uint32_t inv_cnt; /* Invalid entries counter. */ 349c373c52SSuanming Mou } __rte_cache_aligned; 359c373c52SSuanming Mou 369c373c52SSuanming Mou /** 379c373c52SSuanming Mou * Type of callback function for entry removal. 389c373c52SSuanming Mou * 396507c9f5SSuanming Mou * @param tool_ctx 406507c9f5SSuanming Mou * The tool instance user context. 419c373c52SSuanming Mou * @param entry 429c373c52SSuanming Mou * The entry in the list. 439c373c52SSuanming Mou */ 446507c9f5SSuanming Mou typedef void (*mlx5_list_remove_cb)(void *tool_ctx, 459c373c52SSuanming Mou struct mlx5_list_entry *entry); 469c373c52SSuanming Mou 479c373c52SSuanming Mou /** 489c373c52SSuanming Mou * Type of function for user defined matching. 499c373c52SSuanming Mou * 506507c9f5SSuanming Mou * @param tool_ctx 516507c9f5SSuanming Mou * The tool instance context. 529c373c52SSuanming Mou * @param entry 539c373c52SSuanming Mou * The entry in the list. 549c373c52SSuanming Mou * @param ctx 559c373c52SSuanming Mou * The pointer to new entry context. 569c373c52SSuanming Mou * 579c373c52SSuanming Mou * @return 589c373c52SSuanming Mou * 0 if matching, non-zero number otherwise. 599c373c52SSuanming Mou */ 606507c9f5SSuanming Mou typedef int (*mlx5_list_match_cb)(void *tool_ctx, 619c373c52SSuanming Mou struct mlx5_list_entry *entry, void *ctx); 629c373c52SSuanming Mou 636507c9f5SSuanming Mou typedef struct mlx5_list_entry *(*mlx5_list_clone_cb)(void *tool_ctx, 649c373c52SSuanming Mou struct mlx5_list_entry *entry, void *ctx); 659c373c52SSuanming Mou 666507c9f5SSuanming Mou typedef void (*mlx5_list_clone_free_cb)(void *tool_ctx, 679c373c52SSuanming Mou struct mlx5_list_entry *entry); 689c373c52SSuanming Mou 699c373c52SSuanming Mou /** 709c373c52SSuanming Mou * Type of function for user defined mlx5 list entry creation. 719c373c52SSuanming Mou * 726507c9f5SSuanming Mou * @param tool_ctx 736507c9f5SSuanming Mou * The mlx5 tool instance context. 749c373c52SSuanming Mou * @param ctx 759c373c52SSuanming Mou * The pointer to new entry context. 769c373c52SSuanming Mou * 779c373c52SSuanming Mou * @return 789c373c52SSuanming Mou * Pointer of entry on success, NULL otherwise. 799c373c52SSuanming Mou */ 806507c9f5SSuanming Mou typedef struct mlx5_list_entry *(*mlx5_list_create_cb)(void *tool_ctx, 819c373c52SSuanming Mou void *ctx); 829c373c52SSuanming Mou 839c373c52SSuanming Mou /** 84*9a4c3688SSuanming Mou * Linked mlx5 list constant object. 85*9a4c3688SSuanming Mou */ 86*9a4c3688SSuanming Mou struct mlx5_list_const { 87*9a4c3688SSuanming Mou char name[MLX5_NAME_SIZE]; /**< Name of the mlx5 list. */ 88*9a4c3688SSuanming Mou void *ctx; /* user objects target to callback. */ 89*9a4c3688SSuanming Mou bool lcores_share; /* Whether to share objects between the lcores. */ 90*9a4c3688SSuanming Mou mlx5_list_create_cb cb_create; /**< entry create callback. */ 91*9a4c3688SSuanming Mou mlx5_list_match_cb cb_match; /**< entry match callback. */ 92*9a4c3688SSuanming Mou mlx5_list_remove_cb cb_remove; /**< entry remove callback. */ 93*9a4c3688SSuanming Mou mlx5_list_clone_cb cb_clone; /**< entry clone callback. */ 94*9a4c3688SSuanming Mou mlx5_list_clone_free_cb cb_clone_free; 95*9a4c3688SSuanming Mou /**< entry clone free callback. */ 96*9a4c3688SSuanming Mou }; 97*9a4c3688SSuanming Mou 98*9a4c3688SSuanming Mou /** 99*9a4c3688SSuanming Mou * Linked mlx5 list inconstant data. 100*9a4c3688SSuanming Mou */ 101*9a4c3688SSuanming Mou struct mlx5_list_inconst { 102*9a4c3688SSuanming Mou rte_rwlock_t lock; /* read/write lock. */ 103*9a4c3688SSuanming Mou volatile uint32_t gen_cnt; /* List modification may update it. */ 104*9a4c3688SSuanming Mou volatile uint32_t count; /* number of entries in list. */ 105*9a4c3688SSuanming Mou struct mlx5_list_cache *cache[RTE_MAX_LCORE + 1]; 106*9a4c3688SSuanming Mou /* Lcore cache, last index is the global cache. */ 107*9a4c3688SSuanming Mou }; 108*9a4c3688SSuanming Mou 109*9a4c3688SSuanming Mou /** 1109c373c52SSuanming Mou * Linked mlx5 list structure. 1119c373c52SSuanming Mou * 1129c373c52SSuanming Mou * Entry in mlx5 list could be reused if entry already exists, 1139c373c52SSuanming Mou * reference count will increase and the existing entry returns. 1149c373c52SSuanming Mou * 1159c373c52SSuanming Mou * When destroy an entry from list, decrease reference count and only 1169c373c52SSuanming Mou * destroy when no further reference. 1179c373c52SSuanming Mou * 1189c373c52SSuanming Mou * Linked list is designed for limited number of entries, 1199c373c52SSuanming Mou * read mostly, less modification. 1209c373c52SSuanming Mou * 1219c373c52SSuanming Mou * For huge amount of entries, please consider hash list. 1229c373c52SSuanming Mou * 1239c373c52SSuanming Mou */ 1249c373c52SSuanming Mou struct mlx5_list { 125*9a4c3688SSuanming Mou struct mlx5_list_const l_const; 126*9a4c3688SSuanming Mou struct mlx5_list_inconst l_inconst; 1279c373c52SSuanming Mou }; 1289c373c52SSuanming Mou 1299c373c52SSuanming Mou /** 1309c373c52SSuanming Mou * Create a mlx5 list. 1319c373c52SSuanming Mou * 132d03b7860SSuanming Mou * For actions in SW-steering is only memory and can be allowed 133d03b7860SSuanming Mou * to create duplicate objects, the lists don't need to check if 134d03b7860SSuanming Mou * there are existing same objects in other sub local lists, 135d03b7860SSuanming Mou * search the object only in local list will be more efficient. 136d03b7860SSuanming Mou * 1379c373c52SSuanming Mou * @param list 1389c373c52SSuanming Mou * Pointer to the hast list table. 1399c373c52SSuanming Mou * @param name 1409c373c52SSuanming Mou * Name of the mlx5 list. 1419c373c52SSuanming Mou * @param ctx 1429c373c52SSuanming Mou * Pointer to the list context data. 143d03b7860SSuanming Mou * @param lcores_share 144d03b7860SSuanming Mou * Whether to share objects between the lcores. 1459c373c52SSuanming Mou * @param cb_create 1469c373c52SSuanming Mou * Callback function for entry create. 1479c373c52SSuanming Mou * @param cb_match 1489c373c52SSuanming Mou * Callback function for entry match. 1499c373c52SSuanming Mou * @param cb_remove 1509c373c52SSuanming Mou * Callback function for entry remove. 1519c373c52SSuanming Mou * @return 1529c373c52SSuanming Mou * List pointer on success, otherwise NULL. 1539c373c52SSuanming Mou */ 1549c373c52SSuanming Mou __rte_internal 1559c373c52SSuanming Mou struct mlx5_list *mlx5_list_create(const char *name, void *ctx, 156d03b7860SSuanming Mou bool lcores_share, 1579c373c52SSuanming Mou mlx5_list_create_cb cb_create, 1589c373c52SSuanming Mou mlx5_list_match_cb cb_match, 1599c373c52SSuanming Mou mlx5_list_remove_cb cb_remove, 1609c373c52SSuanming Mou mlx5_list_clone_cb cb_clone, 1619c373c52SSuanming Mou mlx5_list_clone_free_cb cb_clone_free); 1629c373c52SSuanming Mou 1639c373c52SSuanming Mou /** 1649c373c52SSuanming Mou * Search an entry matching the key. 1659c373c52SSuanming Mou * 1669c373c52SSuanming Mou * Result returned might be destroyed by other thread, must use 1679c373c52SSuanming Mou * this function only in main thread. 1689c373c52SSuanming Mou * 1699c373c52SSuanming Mou * @param list 1709c373c52SSuanming Mou * Pointer to the mlx5 list. 1719c373c52SSuanming Mou * @param ctx 1729c373c52SSuanming Mou * Common context parameter used by entry callback function. 1739c373c52SSuanming Mou * 1749c373c52SSuanming Mou * @return 1759c373c52SSuanming Mou * Pointer of the list entry if found, NULL otherwise. 1769c373c52SSuanming Mou */ 1779c373c52SSuanming Mou __rte_internal 1789c373c52SSuanming Mou struct mlx5_list_entry *mlx5_list_lookup(struct mlx5_list *list, 1799c373c52SSuanming Mou void *ctx); 1809c373c52SSuanming Mou 1819c373c52SSuanming Mou /** 1829c373c52SSuanming Mou * Reuse or create an entry to the mlx5 list. 1839c373c52SSuanming Mou * 1849c373c52SSuanming Mou * @param list 1859c373c52SSuanming Mou * Pointer to the hast list table. 1869c373c52SSuanming Mou * @param ctx 1879c373c52SSuanming Mou * Common context parameter used by callback function. 1889c373c52SSuanming Mou * 1899c373c52SSuanming Mou * @return 1909c373c52SSuanming Mou * registered entry on success, NULL otherwise 1919c373c52SSuanming Mou */ 1929c373c52SSuanming Mou __rte_internal 1939c373c52SSuanming Mou struct mlx5_list_entry *mlx5_list_register(struct mlx5_list *list, 1949c373c52SSuanming Mou void *ctx); 1959c373c52SSuanming Mou 1969c373c52SSuanming Mou /** 1979c373c52SSuanming Mou * Remove an entry from the mlx5 list. 1989c373c52SSuanming Mou * 1999c373c52SSuanming Mou * User should guarantee the validity of the entry. 2009c373c52SSuanming Mou * 2019c373c52SSuanming Mou * @param list 2029c373c52SSuanming Mou * Pointer to the hast list. 2039c373c52SSuanming Mou * @param entry 2049c373c52SSuanming Mou * Entry to be removed from the mlx5 list table. 2059c373c52SSuanming Mou * @return 2069c373c52SSuanming Mou * 0 on entry removed, 1 on entry still referenced. 2079c373c52SSuanming Mou */ 2089c373c52SSuanming Mou __rte_internal 2099c373c52SSuanming Mou int mlx5_list_unregister(struct mlx5_list *list, 2109c373c52SSuanming Mou struct mlx5_list_entry *entry); 2119c373c52SSuanming Mou 2129c373c52SSuanming Mou /** 2139c373c52SSuanming Mou * Destroy the mlx5 list. 2149c373c52SSuanming Mou * 2159c373c52SSuanming Mou * @param list 2169c373c52SSuanming Mou * Pointer to the mlx5 list. 2179c373c52SSuanming Mou */ 2189c373c52SSuanming Mou __rte_internal 2199c373c52SSuanming Mou void mlx5_list_destroy(struct mlx5_list *list); 2209c373c52SSuanming Mou 2219c373c52SSuanming Mou /** 2229c373c52SSuanming Mou * Get entry number from the mlx5 list. 2239c373c52SSuanming Mou * 2249c373c52SSuanming Mou * @param list 2259c373c52SSuanming Mou * Pointer to the hast list. 2269c373c52SSuanming Mou * @return 2279c373c52SSuanming Mou * mlx5 list entry number. 2289c373c52SSuanming Mou */ 2299c373c52SSuanming Mou __rte_internal 2309c373c52SSuanming Mou uint32_t 2319c373c52SSuanming Mou mlx5_list_get_entry_num(struct mlx5_list *list); 2329c373c52SSuanming Mou 233961b6774SMatan Azrad /********************* Hash List **********************/ 2349c373c52SSuanming Mou 235961b6774SMatan Azrad /* Hash list bucket. */ 23625245d5dSShiri Kuzin struct mlx5_hlist_bucket { 237*9a4c3688SSuanming Mou struct mlx5_list_inconst l; 23825245d5dSShiri Kuzin } __rte_cache_aligned; 23925245d5dSShiri Kuzin 24025245d5dSShiri Kuzin /** 24125245d5dSShiri Kuzin * Hash list table structure 24225245d5dSShiri Kuzin * 243961b6774SMatan Azrad * The hash list bucket using the mlx5_list object for managing. 24425245d5dSShiri Kuzin */ 24525245d5dSShiri Kuzin struct mlx5_hlist { 246961b6774SMatan Azrad uint32_t mask; /* A mask for the bucket index range. */ 247961b6774SMatan Azrad uint8_t flags; 248961b6774SMatan Azrad bool direct_key; /* Whether to use the key directly as hash index. */ 249*9a4c3688SSuanming Mou struct mlx5_list_const l_const; /* List constant data. */ 25025245d5dSShiri Kuzin struct mlx5_hlist_bucket buckets[] __rte_cache_aligned; 25125245d5dSShiri Kuzin }; 25225245d5dSShiri Kuzin 25325245d5dSShiri Kuzin /** 25425245d5dSShiri Kuzin * Create a hash list table, the user can specify the list heads array size 25525245d5dSShiri Kuzin * of the table, now the size should be a power of 2 in order to get better 25625245d5dSShiri Kuzin * distribution for the entries. Each entry is a part of the whole data element 25725245d5dSShiri Kuzin * and the caller should be responsible for the data element's allocation and 25825245d5dSShiri Kuzin * cleanup / free. Key of each entry will be calculated with CRC in order to 25925245d5dSShiri Kuzin * generate a little fairer distribution. 26025245d5dSShiri Kuzin * 26125245d5dSShiri Kuzin * @param name 26225245d5dSShiri Kuzin * Name of the hash list(optional). 26325245d5dSShiri Kuzin * @param size 26425245d5dSShiri Kuzin * Heads array size of the hash list. 26525245d5dSShiri Kuzin * @param entry_size 26625245d5dSShiri Kuzin * Entry size to allocate if cb_create not specified. 267961b6774SMatan Azrad * @param direct key 268961b6774SMatan Azrad * Whether to use the key directly as hash index. 269961b6774SMatan Azrad * @param lcores_share 270961b6774SMatan Azrad * Whether to share objects between the lcores. 271961b6774SMatan Azrad * @param ctx 272961b6774SMatan Azrad * The hlist instance context. 27325245d5dSShiri Kuzin * @param cb_create 27425245d5dSShiri Kuzin * Callback function for entry create. 27525245d5dSShiri Kuzin * @param cb_match 27625245d5dSShiri Kuzin * Callback function for entry match. 277961b6774SMatan Azrad * @param cb_remove 278961b6774SMatan Azrad * Callback function for entry remove. 279961b6774SMatan Azrad * @param cb_clone 280961b6774SMatan Azrad * Callback function for entry clone. 281961b6774SMatan Azrad * @param cb_clone_free 282961b6774SMatan Azrad * Callback function for entry clone free. 28325245d5dSShiri Kuzin * @return 28425245d5dSShiri Kuzin * Pointer of the hash list table created, NULL on failure. 28525245d5dSShiri Kuzin */ 28625245d5dSShiri Kuzin __rte_internal 28725245d5dSShiri Kuzin struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size, 288961b6774SMatan Azrad bool direct_key, bool lcores_share, 289961b6774SMatan Azrad void *ctx, mlx5_list_create_cb cb_create, 290961b6774SMatan Azrad mlx5_list_match_cb cb_match, 291961b6774SMatan Azrad mlx5_list_remove_cb cb_remove, 292961b6774SMatan Azrad mlx5_list_clone_cb cb_clone, 293961b6774SMatan Azrad mlx5_list_clone_free_cb cb_clone_free); 29425245d5dSShiri Kuzin 29525245d5dSShiri Kuzin /** 29625245d5dSShiri Kuzin * Search an entry matching the key. 29725245d5dSShiri Kuzin * 29825245d5dSShiri Kuzin * Result returned might be destroyed by other thread, must use 29925245d5dSShiri Kuzin * this function only in main thread. 30025245d5dSShiri Kuzin * 30125245d5dSShiri Kuzin * @param h 30225245d5dSShiri Kuzin * Pointer to the hast list table. 30325245d5dSShiri Kuzin * @param key 30425245d5dSShiri Kuzin * Key for the searching entry. 30525245d5dSShiri Kuzin * @param ctx 30625245d5dSShiri Kuzin * Common context parameter used by entry callback function. 30725245d5dSShiri Kuzin * 30825245d5dSShiri Kuzin * @return 30925245d5dSShiri Kuzin * Pointer of the hlist entry if found, NULL otherwise. 31025245d5dSShiri Kuzin */ 31125245d5dSShiri Kuzin __rte_internal 312961b6774SMatan Azrad struct mlx5_list_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, 31325245d5dSShiri Kuzin void *ctx); 31425245d5dSShiri Kuzin 31525245d5dSShiri Kuzin /** 31625245d5dSShiri Kuzin * Insert an entry to the hash list table, the entry is only part of whole data 31725245d5dSShiri Kuzin * element and a 64B key is used for matching. User should construct the key or 31825245d5dSShiri Kuzin * give a calculated hash signature and guarantee there is no collision. 31925245d5dSShiri Kuzin * 32025245d5dSShiri Kuzin * @param h 32125245d5dSShiri Kuzin * Pointer to the hast list table. 32225245d5dSShiri Kuzin * @param entry 32325245d5dSShiri Kuzin * Entry to be inserted into the hash list table. 32425245d5dSShiri Kuzin * @param ctx 32525245d5dSShiri Kuzin * Common context parameter used by callback function. 32625245d5dSShiri Kuzin * 32725245d5dSShiri Kuzin * @return 32825245d5dSShiri Kuzin * registered entry on success, NULL otherwise 32925245d5dSShiri Kuzin */ 33025245d5dSShiri Kuzin __rte_internal 331961b6774SMatan Azrad struct mlx5_list_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key, 33225245d5dSShiri Kuzin void *ctx); 33325245d5dSShiri Kuzin 33425245d5dSShiri Kuzin /** 33525245d5dSShiri Kuzin * Remove an entry from the hash list table. User should guarantee the validity 33625245d5dSShiri Kuzin * of the entry. 33725245d5dSShiri Kuzin * 33825245d5dSShiri Kuzin * @param h 33925245d5dSShiri Kuzin * Pointer to the hast list table. (not used) 34025245d5dSShiri Kuzin * @param entry 34125245d5dSShiri Kuzin * Entry to be removed from the hash list table. 34225245d5dSShiri Kuzin * @return 34325245d5dSShiri Kuzin * 0 on entry removed, 1 on entry still referenced. 34425245d5dSShiri Kuzin */ 34525245d5dSShiri Kuzin __rte_internal 346961b6774SMatan Azrad int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_list_entry *entry); 34725245d5dSShiri Kuzin 34825245d5dSShiri Kuzin /** 34925245d5dSShiri Kuzin * Destroy the hash list table, all the entries already inserted into the lists 35025245d5dSShiri Kuzin * will be handled by the callback function provided by the user (including 35125245d5dSShiri Kuzin * free if needed) before the table is freed. 35225245d5dSShiri Kuzin * 35325245d5dSShiri Kuzin * @param h 35425245d5dSShiri Kuzin * Pointer to the hast list table. 35525245d5dSShiri Kuzin */ 35625245d5dSShiri Kuzin __rte_internal 35725245d5dSShiri Kuzin void mlx5_hlist_destroy(struct mlx5_hlist *h); 3587b4f1e6bSMatan Azrad 3597b4f1e6bSMatan Azrad #endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */ 360