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