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