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