xref: /dpdk/drivers/common/mlx5/mlx5_common_utils.h (revision e77506397fc8005c5129e22e9e2d15d5876790fd)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2019 Mellanox Technologies, Ltd
3  */
4 
5 #ifndef RTE_PMD_MLX5_COMMON_UTILS_H_
6 #define RTE_PMD_MLX5_COMMON_UTILS_H_
7 
8 #include <rte_compat.h>
9 #include <rte_rwlock.h>
10 
11 #include "mlx5_common.h"
12 
13 /************************ mlx5 list *****************************/
14 
15 /** Maximum size of string for naming. */
16 #define MLX5_NAME_SIZE			32
17 /** Maximum size of list. */
18 #define MLX5_LIST_MAX			(RTE_MAX_LCORE + 2)
19 /** Global list index. */
20 #define MLX5_LIST_GLOBAL		((MLX5_LIST_MAX) - 1)
21 /** None rte core list index. */
22 #define MLX5_LIST_NLCORE		((MLX5_LIST_MAX) - 2)
23 
24 struct mlx5_list;
25 
26 /**
27  * Structure of the entry in the mlx5 list, user should define its own struct
28  * that contains this in order to store the data.
29  */
30 struct __rte_packed_begin mlx5_list_entry {
31 	LIST_ENTRY(mlx5_list_entry) next; /* Entry pointers in the list. */
32 	alignas(8) RTE_ATOMIC(uint32_t) ref_cnt; /* 0 means, entry is invalid. */
33 	uint32_t lcore_idx;
34 	union {
35 		struct mlx5_list_entry *gentry;
36 		uint32_t bucket_idx;
37 	};
38 } __rte_packed_end;
39 
40 struct __rte_cache_aligned mlx5_list_cache {
41 	LIST_HEAD(mlx5_list_head, mlx5_list_entry) h;
42 	RTE_ATOMIC(uint32_t) inv_cnt; /* Invalid entries counter. */
43 };
44 
45 /**
46  * Type of callback function for entry removal.
47  *
48  * @param tool_ctx
49  *   The tool instance user context.
50  * @param entry
51  *   The entry in the list.
52  */
53 typedef void (*mlx5_list_remove_cb)(void *tool_ctx,
54 				    struct mlx5_list_entry *entry);
55 
56 /**
57  * Type of function for user defined matching.
58  *
59  * @param tool_ctx
60  *   The tool instance context.
61  * @param entry
62  *   The entry in the list.
63  * @param ctx
64  *   The pointer to new entry context.
65  *
66  * @return
67  *   0 if matching, non-zero number otherwise.
68  */
69 typedef int (*mlx5_list_match_cb)(void *tool_ctx,
70 				   struct mlx5_list_entry *entry, void *ctx);
71 
72 typedef struct mlx5_list_entry *(*mlx5_list_clone_cb)(void *tool_ctx,
73 				      struct mlx5_list_entry *entry, void *ctx);
74 
75 typedef void (*mlx5_list_clone_free_cb)(void *tool_ctx,
76 					struct mlx5_list_entry *entry);
77 
78 /**
79  * Type of function for user defined mlx5 list entry creation.
80  *
81  * @param tool_ctx
82  *   The mlx5 tool instance context.
83  * @param ctx
84  *   The pointer to new entry context.
85  *
86  * @return
87  *   Pointer of entry on success, NULL otherwise.
88  */
89 typedef struct mlx5_list_entry *(*mlx5_list_create_cb)(void *tool_ctx,
90 						       void *ctx);
91 
92 /**
93  * Linked mlx5 list constant object.
94  */
95 struct mlx5_list_const {
96 	char name[MLX5_NAME_SIZE]; /**< Name of the mlx5 list. */
97 	void *ctx; /* user objects target to callback. */
98 	bool lcores_share; /* Whether to share objects between the lcores. */
99 	rte_spinlock_t lcore_lock; /* Lock for non-lcore list. */
100 	mlx5_list_create_cb cb_create; /**< entry create callback. */
101 	mlx5_list_match_cb cb_match; /**< entry match callback. */
102 	mlx5_list_remove_cb cb_remove; /**< entry remove callback. */
103 	mlx5_list_clone_cb cb_clone; /**< entry clone callback. */
104 	mlx5_list_clone_free_cb cb_clone_free;
105 	/**< entry clone free callback. */
106 };
107 
108 /**
109  * Linked mlx5 list inconstant data.
110  */
111 struct mlx5_list_inconst {
112 	rte_rwlock_t lock; /* read/write lock. */
113 	volatile uint32_t gen_cnt; /* List modification may update it. */
114 	volatile RTE_ATOMIC(uint32_t) count; /* number of entries in list. */
115 	struct mlx5_list_cache *cache[MLX5_LIST_MAX];
116 	/* Lcore cache, last index is the global cache. */
117 };
118 
119 /**
120  * Linked mlx5 list structure.
121  *
122  * Entry in mlx5 list could be reused if entry already exists,
123  * reference count will increase and the existing entry returns.
124  *
125  * When destroy an entry from list, decrease reference count and only
126  * destroy when no further reference.
127  *
128  * Linked list is designed for limited number of entries,
129  * read mostly, less modification.
130  *
131  * For huge amount of entries, please consider hash list.
132  *
133  */
134 struct __rte_aligned(16) mlx5_list {
135 	struct mlx5_list_const l_const;
136 	struct mlx5_list_inconst l_inconst;
137 };
138 
139 /**
140  * Create a mlx5 list.
141  *
142  * For actions in SW-steering is only memory and  can be allowed
143  * to create duplicate objects, the lists don't need to check if
144  * there are existing same objects in other sub local lists,
145  * search the object only in local list will be more efficient.
146  *
147  * @param list
148  *   Pointer to the hast list table.
149  * @param name
150  *   Name of the mlx5 list.
151  * @param ctx
152  *   Pointer to the list context data.
153  * @param lcores_share
154  *   Whether to share objects between the lcores.
155  * @param cb_create
156  *   Callback function for entry create.
157  * @param cb_match
158  *   Callback function for entry match.
159  * @param cb_remove
160  *   Callback function for entry remove.
161  * @return
162  *   List pointer on success, otherwise NULL.
163  */
164 __rte_internal
165 struct mlx5_list *mlx5_list_create(const char *name, void *ctx,
166 				   bool lcores_share,
167 				   mlx5_list_create_cb cb_create,
168 				   mlx5_list_match_cb cb_match,
169 				   mlx5_list_remove_cb cb_remove,
170 				   mlx5_list_clone_cb cb_clone,
171 				   mlx5_list_clone_free_cb cb_clone_free);
172 
173 /**
174  * Search an entry matching the key.
175  *
176  * Result returned might be destroyed by other thread, must use
177  * this function only in main thread.
178  *
179  * @param list
180  *   Pointer to the mlx5 list.
181  * @param ctx
182  *   Common context parameter used by entry callback function.
183  *
184  * @return
185  *   Pointer of the list entry if found, NULL otherwise.
186  */
187 __rte_internal
188 struct mlx5_list_entry *mlx5_list_lookup(struct mlx5_list *list,
189 					   void *ctx);
190 
191 /**
192  * Reuse or create an entry to the mlx5 list.
193  *
194  * @param list
195  *   Pointer to the hast list table.
196  * @param ctx
197  *   Common context parameter used by callback function.
198  *
199  * @return
200  *   registered entry on success, NULL otherwise
201  */
202 __rte_internal
203 struct mlx5_list_entry *mlx5_list_register(struct mlx5_list *list,
204 					     void *ctx);
205 
206 /**
207  * Remove an entry from the mlx5 list.
208  *
209  * User should guarantee the validity of the entry.
210  *
211  * @param list
212  *   Pointer to the hast list.
213  * @param entry
214  *   Entry to be removed from the mlx5 list table.
215  * @return
216  *   0 on entry removed, 1 on entry still referenced.
217  */
218 __rte_internal
219 int mlx5_list_unregister(struct mlx5_list *list,
220 			  struct mlx5_list_entry *entry);
221 
222 /**
223  * Destroy the mlx5 list.
224  *
225  * @param list
226  *   Pointer to the mlx5 list.
227  */
228 __rte_internal
229 void mlx5_list_destroy(struct mlx5_list *list);
230 
231 /**
232  * Get entry number from the mlx5 list.
233  *
234  * @param list
235  *   Pointer to the hast list.
236  * @return
237  *   mlx5 list entry number.
238  */
239 __rte_internal
240 uint32_t
241 mlx5_list_get_entry_num(struct mlx5_list *list);
242 
243 /********************* Hash List **********************/
244 
245 /* Hash list bucket. */
246 struct __rte_cache_aligned mlx5_hlist_bucket {
247 	struct mlx5_list_inconst l;
248 };
249 
250 /**
251  * Hash list table structure
252  *
253  * The hash list bucket using the mlx5_list object for managing.
254  */
255 struct mlx5_hlist {
256 	uint32_t mask; /* A mask for the bucket index range. */
257 	uint8_t flags;
258 	bool direct_key; /* Whether to use the key directly as hash index. */
259 	struct mlx5_list_const l_const; /* List constant data. */
260 	alignas(RTE_CACHE_LINE_SIZE) struct mlx5_hlist_bucket buckets[];
261 };
262 
263 /**
264  * Create a hash list table, the user can specify the list heads array size
265  * of the table, now the size should be a power of 2 in order to get better
266  * distribution for the entries. Each entry is a part of the whole data element
267  * and the caller should be responsible for the data element's allocation and
268  * cleanup / free. Key of each entry will be calculated with CRC in order to
269  * generate a little fairer distribution.
270  *
271  * @param name
272  *   Name of the hash list(optional).
273  * @param size
274  *   Heads array size of the hash list.
275  * @param entry_size
276  *   Entry size to allocate if cb_create not specified.
277  * @param direct key
278  *   Whether to use the key directly as hash index.
279  * @param lcores_share
280  *   Whether to share objects between the lcores.
281  * @param ctx
282  *   The hlist instance context.
283  * @param cb_create
284  *   Callback function for entry create.
285  * @param cb_match
286  *   Callback function for entry match.
287  * @param cb_remove
288  *   Callback function for entry remove.
289  * @param cb_clone
290  *   Callback function for entry clone.
291  * @param cb_clone_free
292  *   Callback function for entry clone free.
293  * @return
294  *   Pointer of the hash list table created, NULL on failure.
295  */
296 __rte_internal
297 struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size,
298 				     bool direct_key, bool lcores_share,
299 				     void *ctx, mlx5_list_create_cb cb_create,
300 				     mlx5_list_match_cb cb_match,
301 				     mlx5_list_remove_cb cb_remove,
302 				     mlx5_list_clone_cb cb_clone,
303 				     mlx5_list_clone_free_cb cb_clone_free);
304 
305 /**
306  * Search an entry matching the key.
307  *
308  * Result returned might be destroyed by other thread, must use
309  * this function only in main thread.
310  *
311  * @param h
312  *   Pointer to the hast list table.
313  * @param key
314  *   Key for the searching entry.
315  * @param ctx
316  *   Common context parameter used by entry callback function.
317  *
318  * @return
319  *   Pointer of the hlist entry if found, NULL otherwise.
320  */
321 __rte_internal
322 struct mlx5_list_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key,
323 					   void *ctx);
324 
325 /**
326  * Insert an entry to the hash list table, the entry is only part of whole data
327  * element and a 64B key is used for matching. User should construct the key or
328  * give a calculated hash signature and guarantee there is no collision.
329  *
330  * @param h
331  *   Pointer to the hast list table.
332  * @param entry
333  *   Entry to be inserted into the hash list table.
334  * @param ctx
335  *   Common context parameter used by callback function.
336  *
337  * @return
338  *   registered entry on success, NULL otherwise
339  */
340 __rte_internal
341 struct mlx5_list_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key,
342 					     void *ctx);
343 
344 /**
345  * Remove an entry from the hash list table. User should guarantee the validity
346  * of the entry.
347  *
348  * @param h
349  *   Pointer to the hast list table. (not used)
350  * @param entry
351  *   Entry to be removed from the hash list table.
352  * @return
353  *   0 on entry removed, 1 on entry still referenced.
354  */
355 __rte_internal
356 int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_list_entry *entry);
357 
358 /**
359  * Destroy the hash list table, all the entries already inserted into the lists
360  * will be handled by the callback function provided by the user (including
361  * free if needed) before the table is freed.
362  *
363  * @param h
364  *   Pointer to the hast list table.
365  */
366 __rte_internal
367 void mlx5_hlist_destroy(struct mlx5_hlist *h);
368 
369 #endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */
370