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