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 81094dd94SDavid Marchand #include <rte_compat.h> 9ad435d32SXueming Li #include <rte_rwlock.h> 10ad435d32SXueming Li 117b4f1e6bSMatan Azrad #include "mlx5_common.h" 127b4f1e6bSMatan Azrad 139c373c52SSuanming Mou /************************ mlx5 list *****************************/ 149c373c52SSuanming Mou 159c373c52SSuanming Mou /** Maximum size of string for naming. */ 169c373c52SSuanming Mou #define MLX5_NAME_SIZE 32 177e1cf892SSuanming Mou /** Maximum size of list. */ 187e1cf892SSuanming Mou #define MLX5_LIST_MAX (RTE_MAX_LCORE + 2) 197e1cf892SSuanming Mou /** Global list index. */ 207e1cf892SSuanming Mou #define MLX5_LIST_GLOBAL ((MLX5_LIST_MAX) - 1) 217e1cf892SSuanming Mou /** None rte core list index. */ 227e1cf892SSuanming Mou #define MLX5_LIST_NLCORE ((MLX5_LIST_MAX) - 2) 239c373c52SSuanming Mou 249c373c52SSuanming Mou struct mlx5_list; 259c373c52SSuanming Mou 269c373c52SSuanming Mou /** 279c373c52SSuanming Mou * Structure of the entry in the mlx5 list, user should define its own struct 289c373c52SSuanming Mou * that contains this in order to store the data. 299c373c52SSuanming Mou */ 30*e7750639SAndre Muezerie struct __rte_packed_begin mlx5_list_entry { 319c373c52SSuanming Mou LIST_ENTRY(mlx5_list_entry) next; /* Entry pointers in the list. */ 32e12a0166STyler Retzlaff alignas(8) RTE_ATOMIC(uint32_t) ref_cnt; /* 0 means, entry is invalid. */ 339c373c52SSuanming Mou uint32_t lcore_idx; 34961b6774SMatan Azrad union { 359c373c52SSuanming Mou struct mlx5_list_entry *gentry; 36961b6774SMatan Azrad uint32_t bucket_idx; 379c373c52SSuanming Mou }; 38*e7750639SAndre Muezerie } __rte_packed_end; 399c373c52SSuanming Mou 4027595cd8STyler Retzlaff struct __rte_cache_aligned mlx5_list_cache { 419c373c52SSuanming Mou LIST_HEAD(mlx5_list_head, mlx5_list_entry) h; 42e12a0166STyler Retzlaff RTE_ATOMIC(uint32_t) inv_cnt; /* Invalid entries counter. */ 4327595cd8STyler Retzlaff }; 449c373c52SSuanming Mou 459c373c52SSuanming Mou /** 469c373c52SSuanming Mou * Type of callback function for entry removal. 479c373c52SSuanming Mou * 486507c9f5SSuanming Mou * @param tool_ctx 496507c9f5SSuanming Mou * The tool instance user context. 509c373c52SSuanming Mou * @param entry 519c373c52SSuanming Mou * The entry in the list. 529c373c52SSuanming Mou */ 536507c9f5SSuanming Mou typedef void (*mlx5_list_remove_cb)(void *tool_ctx, 549c373c52SSuanming Mou struct mlx5_list_entry *entry); 559c373c52SSuanming Mou 569c373c52SSuanming Mou /** 579c373c52SSuanming Mou * Type of function for user defined matching. 589c373c52SSuanming Mou * 596507c9f5SSuanming Mou * @param tool_ctx 606507c9f5SSuanming Mou * The tool instance context. 619c373c52SSuanming Mou * @param entry 629c373c52SSuanming Mou * The entry in the list. 639c373c52SSuanming Mou * @param ctx 649c373c52SSuanming Mou * The pointer to new entry context. 659c373c52SSuanming Mou * 669c373c52SSuanming Mou * @return 679c373c52SSuanming Mou * 0 if matching, non-zero number otherwise. 689c373c52SSuanming Mou */ 696507c9f5SSuanming Mou typedef int (*mlx5_list_match_cb)(void *tool_ctx, 709c373c52SSuanming Mou struct mlx5_list_entry *entry, void *ctx); 719c373c52SSuanming Mou 726507c9f5SSuanming Mou typedef struct mlx5_list_entry *(*mlx5_list_clone_cb)(void *tool_ctx, 739c373c52SSuanming Mou struct mlx5_list_entry *entry, void *ctx); 749c373c52SSuanming Mou 756507c9f5SSuanming Mou typedef void (*mlx5_list_clone_free_cb)(void *tool_ctx, 769c373c52SSuanming Mou struct mlx5_list_entry *entry); 779c373c52SSuanming Mou 789c373c52SSuanming Mou /** 799c373c52SSuanming Mou * Type of function for user defined mlx5 list entry creation. 809c373c52SSuanming Mou * 816507c9f5SSuanming Mou * @param tool_ctx 826507c9f5SSuanming Mou * The mlx5 tool instance context. 839c373c52SSuanming Mou * @param ctx 849c373c52SSuanming Mou * The pointer to new entry context. 859c373c52SSuanming Mou * 869c373c52SSuanming Mou * @return 879c373c52SSuanming Mou * Pointer of entry on success, NULL otherwise. 889c373c52SSuanming Mou */ 896507c9f5SSuanming Mou typedef struct mlx5_list_entry *(*mlx5_list_create_cb)(void *tool_ctx, 909c373c52SSuanming Mou void *ctx); 919c373c52SSuanming Mou 929c373c52SSuanming Mou /** 939a4c3688SSuanming Mou * Linked mlx5 list constant object. 949a4c3688SSuanming Mou */ 959a4c3688SSuanming Mou struct mlx5_list_const { 969a4c3688SSuanming Mou char name[MLX5_NAME_SIZE]; /**< Name of the mlx5 list. */ 979a4c3688SSuanming Mou void *ctx; /* user objects target to callback. */ 989a4c3688SSuanming Mou bool lcores_share; /* Whether to share objects between the lcores. */ 997e1cf892SSuanming Mou rte_spinlock_t lcore_lock; /* Lock for non-lcore list. */ 1009a4c3688SSuanming Mou mlx5_list_create_cb cb_create; /**< entry create callback. */ 1019a4c3688SSuanming Mou mlx5_list_match_cb cb_match; /**< entry match callback. */ 1029a4c3688SSuanming Mou mlx5_list_remove_cb cb_remove; /**< entry remove callback. */ 1039a4c3688SSuanming Mou mlx5_list_clone_cb cb_clone; /**< entry clone callback. */ 1049a4c3688SSuanming Mou mlx5_list_clone_free_cb cb_clone_free; 1059a4c3688SSuanming Mou /**< entry clone free callback. */ 1069a4c3688SSuanming Mou }; 1079a4c3688SSuanming Mou 1089a4c3688SSuanming Mou /** 1099a4c3688SSuanming Mou * Linked mlx5 list inconstant data. 1109a4c3688SSuanming Mou */ 1119a4c3688SSuanming Mou struct mlx5_list_inconst { 1129a4c3688SSuanming Mou rte_rwlock_t lock; /* read/write lock. */ 1139a4c3688SSuanming Mou volatile uint32_t gen_cnt; /* List modification may update it. */ 114e12a0166STyler Retzlaff volatile RTE_ATOMIC(uint32_t) count; /* number of entries in list. */ 1157e1cf892SSuanming Mou struct mlx5_list_cache *cache[MLX5_LIST_MAX]; 1169a4c3688SSuanming Mou /* Lcore cache, last index is the global cache. */ 1179a4c3688SSuanming Mou }; 1189a4c3688SSuanming Mou 1199a4c3688SSuanming Mou /** 1209c373c52SSuanming Mou * Linked mlx5 list structure. 1219c373c52SSuanming Mou * 1229c373c52SSuanming Mou * Entry in mlx5 list could be reused if entry already exists, 1239c373c52SSuanming Mou * reference count will increase and the existing entry returns. 1249c373c52SSuanming Mou * 1259c373c52SSuanming Mou * When destroy an entry from list, decrease reference count and only 1269c373c52SSuanming Mou * destroy when no further reference. 1279c373c52SSuanming Mou * 1289c373c52SSuanming Mou * Linked list is designed for limited number of entries, 1299c373c52SSuanming Mou * read mostly, less modification. 1309c373c52SSuanming Mou * 1319c373c52SSuanming Mou * For huge amount of entries, please consider hash list. 1329c373c52SSuanming Mou * 1339c373c52SSuanming Mou */ 13490967539SShani Peretz struct __rte_aligned(16) mlx5_list { 1359a4c3688SSuanming Mou struct mlx5_list_const l_const; 1369a4c3688SSuanming Mou struct mlx5_list_inconst l_inconst; 1379c373c52SSuanming Mou }; 1389c373c52SSuanming Mou 1399c373c52SSuanming Mou /** 1409c373c52SSuanming Mou * Create a mlx5 list. 1419c373c52SSuanming Mou * 142d03b7860SSuanming Mou * For actions in SW-steering is only memory and can be allowed 143d03b7860SSuanming Mou * to create duplicate objects, the lists don't need to check if 144d03b7860SSuanming Mou * there are existing same objects in other sub local lists, 145d03b7860SSuanming Mou * search the object only in local list will be more efficient. 146d03b7860SSuanming Mou * 1479c373c52SSuanming Mou * @param list 1489c373c52SSuanming Mou * Pointer to the hast list table. 1499c373c52SSuanming Mou * @param name 1509c373c52SSuanming Mou * Name of the mlx5 list. 1519c373c52SSuanming Mou * @param ctx 1529c373c52SSuanming Mou * Pointer to the list context data. 153d03b7860SSuanming Mou * @param lcores_share 154d03b7860SSuanming Mou * Whether to share objects between the lcores. 1559c373c52SSuanming Mou * @param cb_create 1569c373c52SSuanming Mou * Callback function for entry create. 1579c373c52SSuanming Mou * @param cb_match 1589c373c52SSuanming Mou * Callback function for entry match. 1599c373c52SSuanming Mou * @param cb_remove 1609c373c52SSuanming Mou * Callback function for entry remove. 1619c373c52SSuanming Mou * @return 1629c373c52SSuanming Mou * List pointer on success, otherwise NULL. 1639c373c52SSuanming Mou */ 1649c373c52SSuanming Mou __rte_internal 1659c373c52SSuanming Mou struct mlx5_list *mlx5_list_create(const char *name, void *ctx, 166d03b7860SSuanming Mou bool lcores_share, 1679c373c52SSuanming Mou mlx5_list_create_cb cb_create, 1689c373c52SSuanming Mou mlx5_list_match_cb cb_match, 1699c373c52SSuanming Mou mlx5_list_remove_cb cb_remove, 1709c373c52SSuanming Mou mlx5_list_clone_cb cb_clone, 1719c373c52SSuanming Mou mlx5_list_clone_free_cb cb_clone_free); 1729c373c52SSuanming Mou 1739c373c52SSuanming Mou /** 1749c373c52SSuanming Mou * Search an entry matching the key. 1759c373c52SSuanming Mou * 1769c373c52SSuanming Mou * Result returned might be destroyed by other thread, must use 1779c373c52SSuanming Mou * this function only in main thread. 1789c373c52SSuanming Mou * 1799c373c52SSuanming Mou * @param list 1809c373c52SSuanming Mou * Pointer to the mlx5 list. 1819c373c52SSuanming Mou * @param ctx 1829c373c52SSuanming Mou * Common context parameter used by entry callback function. 1839c373c52SSuanming Mou * 1849c373c52SSuanming Mou * @return 1859c373c52SSuanming Mou * Pointer of the list entry if found, NULL otherwise. 1869c373c52SSuanming Mou */ 1879c373c52SSuanming Mou __rte_internal 1889c373c52SSuanming Mou struct mlx5_list_entry *mlx5_list_lookup(struct mlx5_list *list, 1899c373c52SSuanming Mou void *ctx); 1909c373c52SSuanming Mou 1919c373c52SSuanming Mou /** 1929c373c52SSuanming Mou * Reuse or create an entry to the mlx5 list. 1939c373c52SSuanming Mou * 1949c373c52SSuanming Mou * @param list 1959c373c52SSuanming Mou * Pointer to the hast list table. 1969c373c52SSuanming Mou * @param ctx 1979c373c52SSuanming Mou * Common context parameter used by callback function. 1989c373c52SSuanming Mou * 1999c373c52SSuanming Mou * @return 2009c373c52SSuanming Mou * registered entry on success, NULL otherwise 2019c373c52SSuanming Mou */ 2029c373c52SSuanming Mou __rte_internal 2039c373c52SSuanming Mou struct mlx5_list_entry *mlx5_list_register(struct mlx5_list *list, 2049c373c52SSuanming Mou void *ctx); 2059c373c52SSuanming Mou 2069c373c52SSuanming Mou /** 2079c373c52SSuanming Mou * Remove an entry from the mlx5 list. 2089c373c52SSuanming Mou * 2099c373c52SSuanming Mou * User should guarantee the validity of the entry. 2109c373c52SSuanming Mou * 2119c373c52SSuanming Mou * @param list 2129c373c52SSuanming Mou * Pointer to the hast list. 2139c373c52SSuanming Mou * @param entry 2149c373c52SSuanming Mou * Entry to be removed from the mlx5 list table. 2159c373c52SSuanming Mou * @return 2169c373c52SSuanming Mou * 0 on entry removed, 1 on entry still referenced. 2179c373c52SSuanming Mou */ 2189c373c52SSuanming Mou __rte_internal 2199c373c52SSuanming Mou int mlx5_list_unregister(struct mlx5_list *list, 2209c373c52SSuanming Mou struct mlx5_list_entry *entry); 2219c373c52SSuanming Mou 2229c373c52SSuanming Mou /** 2239c373c52SSuanming Mou * Destroy the mlx5 list. 2249c373c52SSuanming Mou * 2259c373c52SSuanming Mou * @param list 2269c373c52SSuanming Mou * Pointer to the mlx5 list. 2279c373c52SSuanming Mou */ 2289c373c52SSuanming Mou __rte_internal 2299c373c52SSuanming Mou void mlx5_list_destroy(struct mlx5_list *list); 2309c373c52SSuanming Mou 2319c373c52SSuanming Mou /** 2329c373c52SSuanming Mou * Get entry number from the mlx5 list. 2339c373c52SSuanming Mou * 2349c373c52SSuanming Mou * @param list 2359c373c52SSuanming Mou * Pointer to the hast list. 2369c373c52SSuanming Mou * @return 2379c373c52SSuanming Mou * mlx5 list entry number. 2389c373c52SSuanming Mou */ 2399c373c52SSuanming Mou __rte_internal 2409c373c52SSuanming Mou uint32_t 2419c373c52SSuanming Mou mlx5_list_get_entry_num(struct mlx5_list *list); 2429c373c52SSuanming Mou 243961b6774SMatan Azrad /********************* Hash List **********************/ 2449c373c52SSuanming Mou 245961b6774SMatan Azrad /* Hash list bucket. */ 24627595cd8STyler Retzlaff struct __rte_cache_aligned mlx5_hlist_bucket { 2479a4c3688SSuanming Mou struct mlx5_list_inconst l; 24827595cd8STyler Retzlaff }; 24925245d5dSShiri Kuzin 25025245d5dSShiri Kuzin /** 25125245d5dSShiri Kuzin * Hash list table structure 25225245d5dSShiri Kuzin * 253961b6774SMatan Azrad * The hash list bucket using the mlx5_list object for managing. 25425245d5dSShiri Kuzin */ 25525245d5dSShiri Kuzin struct mlx5_hlist { 256961b6774SMatan Azrad uint32_t mask; /* A mask for the bucket index range. */ 257961b6774SMatan Azrad uint8_t flags; 258961b6774SMatan Azrad bool direct_key; /* Whether to use the key directly as hash index. */ 2599a4c3688SSuanming Mou struct mlx5_list_const l_const; /* List constant data. */ 26027595cd8STyler Retzlaff alignas(RTE_CACHE_LINE_SIZE) struct mlx5_hlist_bucket buckets[]; 26125245d5dSShiri Kuzin }; 26225245d5dSShiri Kuzin 26325245d5dSShiri Kuzin /** 26425245d5dSShiri Kuzin * Create a hash list table, the user can specify the list heads array size 26525245d5dSShiri Kuzin * of the table, now the size should be a power of 2 in order to get better 26625245d5dSShiri Kuzin * distribution for the entries. Each entry is a part of the whole data element 26725245d5dSShiri Kuzin * and the caller should be responsible for the data element's allocation and 26825245d5dSShiri Kuzin * cleanup / free. Key of each entry will be calculated with CRC in order to 26925245d5dSShiri Kuzin * generate a little fairer distribution. 27025245d5dSShiri Kuzin * 27125245d5dSShiri Kuzin * @param name 27225245d5dSShiri Kuzin * Name of the hash list(optional). 27325245d5dSShiri Kuzin * @param size 27425245d5dSShiri Kuzin * Heads array size of the hash list. 27525245d5dSShiri Kuzin * @param entry_size 27625245d5dSShiri Kuzin * Entry size to allocate if cb_create not specified. 277961b6774SMatan Azrad * @param direct key 278961b6774SMatan Azrad * Whether to use the key directly as hash index. 279961b6774SMatan Azrad * @param lcores_share 280961b6774SMatan Azrad * Whether to share objects between the lcores. 281961b6774SMatan Azrad * @param ctx 282961b6774SMatan Azrad * The hlist instance context. 28325245d5dSShiri Kuzin * @param cb_create 28425245d5dSShiri Kuzin * Callback function for entry create. 28525245d5dSShiri Kuzin * @param cb_match 28625245d5dSShiri Kuzin * Callback function for entry match. 287961b6774SMatan Azrad * @param cb_remove 288961b6774SMatan Azrad * Callback function for entry remove. 289961b6774SMatan Azrad * @param cb_clone 290961b6774SMatan Azrad * Callback function for entry clone. 291961b6774SMatan Azrad * @param cb_clone_free 292961b6774SMatan Azrad * Callback function for entry clone free. 29325245d5dSShiri Kuzin * @return 29425245d5dSShiri Kuzin * Pointer of the hash list table created, NULL on failure. 29525245d5dSShiri Kuzin */ 29625245d5dSShiri Kuzin __rte_internal 29725245d5dSShiri Kuzin struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size, 298961b6774SMatan Azrad bool direct_key, bool lcores_share, 299961b6774SMatan Azrad void *ctx, mlx5_list_create_cb cb_create, 300961b6774SMatan Azrad mlx5_list_match_cb cb_match, 301961b6774SMatan Azrad mlx5_list_remove_cb cb_remove, 302961b6774SMatan Azrad mlx5_list_clone_cb cb_clone, 303961b6774SMatan Azrad mlx5_list_clone_free_cb cb_clone_free); 30425245d5dSShiri Kuzin 30525245d5dSShiri Kuzin /** 30625245d5dSShiri Kuzin * Search an entry matching the key. 30725245d5dSShiri Kuzin * 30825245d5dSShiri Kuzin * Result returned might be destroyed by other thread, must use 30925245d5dSShiri Kuzin * this function only in main thread. 31025245d5dSShiri Kuzin * 31125245d5dSShiri Kuzin * @param h 31225245d5dSShiri Kuzin * Pointer to the hast list table. 31325245d5dSShiri Kuzin * @param key 31425245d5dSShiri Kuzin * Key for the searching entry. 31525245d5dSShiri Kuzin * @param ctx 31625245d5dSShiri Kuzin * Common context parameter used by entry callback function. 31725245d5dSShiri Kuzin * 31825245d5dSShiri Kuzin * @return 31925245d5dSShiri Kuzin * Pointer of the hlist entry if found, NULL otherwise. 32025245d5dSShiri Kuzin */ 32125245d5dSShiri Kuzin __rte_internal 322961b6774SMatan Azrad struct mlx5_list_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, 32325245d5dSShiri Kuzin void *ctx); 32425245d5dSShiri Kuzin 32525245d5dSShiri Kuzin /** 32625245d5dSShiri Kuzin * Insert an entry to the hash list table, the entry is only part of whole data 32725245d5dSShiri Kuzin * element and a 64B key is used for matching. User should construct the key or 32825245d5dSShiri Kuzin * give a calculated hash signature and guarantee there is no collision. 32925245d5dSShiri Kuzin * 33025245d5dSShiri Kuzin * @param h 33125245d5dSShiri Kuzin * Pointer to the hast list table. 33225245d5dSShiri Kuzin * @param entry 33325245d5dSShiri Kuzin * Entry to be inserted into the hash list table. 33425245d5dSShiri Kuzin * @param ctx 33525245d5dSShiri Kuzin * Common context parameter used by callback function. 33625245d5dSShiri Kuzin * 33725245d5dSShiri Kuzin * @return 33825245d5dSShiri Kuzin * registered entry on success, NULL otherwise 33925245d5dSShiri Kuzin */ 34025245d5dSShiri Kuzin __rte_internal 341961b6774SMatan Azrad struct mlx5_list_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key, 34225245d5dSShiri Kuzin void *ctx); 34325245d5dSShiri Kuzin 34425245d5dSShiri Kuzin /** 34525245d5dSShiri Kuzin * Remove an entry from the hash list table. User should guarantee the validity 34625245d5dSShiri Kuzin * of the entry. 34725245d5dSShiri Kuzin * 34825245d5dSShiri Kuzin * @param h 34925245d5dSShiri Kuzin * Pointer to the hast list table. (not used) 35025245d5dSShiri Kuzin * @param entry 35125245d5dSShiri Kuzin * Entry to be removed from the hash list table. 35225245d5dSShiri Kuzin * @return 35325245d5dSShiri Kuzin * 0 on entry removed, 1 on entry still referenced. 35425245d5dSShiri Kuzin */ 35525245d5dSShiri Kuzin __rte_internal 356961b6774SMatan Azrad int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_list_entry *entry); 35725245d5dSShiri Kuzin 35825245d5dSShiri Kuzin /** 35925245d5dSShiri Kuzin * Destroy the hash list table, all the entries already inserted into the lists 36025245d5dSShiri Kuzin * will be handled by the callback function provided by the user (including 36125245d5dSShiri Kuzin * free if needed) before the table is freed. 36225245d5dSShiri Kuzin * 36325245d5dSShiri Kuzin * @param h 36425245d5dSShiri Kuzin * Pointer to the hast list table. 36525245d5dSShiri Kuzin */ 36625245d5dSShiri Kuzin __rte_internal 36725245d5dSShiri Kuzin void mlx5_hlist_destroy(struct mlx5_hlist *h); 3687b4f1e6bSMatan Azrad 3697b4f1e6bSMatan Azrad #endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */ 370