xref: /dpdk/drivers/common/mlx5/mlx5_common_utils.h (revision 9a4c36880704438a8801cf4c58a434b04007a91c)
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