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