common/mlx5: share hash list tool
[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 #define MLX5_HLIST_DIRECT_KEY 0x0001 /* Use the key directly as hash index. */
11 #define MLX5_HLIST_WRITE_MOST 0x0002 /* List mostly used for append new. */
12
13 /** Maximum size of string for naming the hlist table. */
14 #define MLX5_HLIST_NAMESIZE                     32
15
16 struct mlx5_hlist;
17
18 /**
19  * Structure of the entry in the hash list, user should define its own struct
20  * that contains this in order to store the data. The 'key' is 64-bits right
21  * now and its user's responsibility to guarantee there is no collision.
22  */
23 struct mlx5_hlist_entry {
24         LIST_ENTRY(mlx5_hlist_entry) next; /* entry pointers in the list. */
25         uint32_t idx; /* Bucket index the entry belongs to. */
26         uint32_t ref_cnt; /* Reference count. */
27 };
28
29 /** Structure for hash head. */
30 LIST_HEAD(mlx5_hlist_head, mlx5_hlist_entry);
31
32 /**
33  * Type of callback function for entry removal.
34  *
35  * @param list
36  *   The hash list.
37  * @param entry
38  *   The entry in the list.
39  */
40 typedef void (*mlx5_hlist_remove_cb)(struct mlx5_hlist *list,
41                                      struct mlx5_hlist_entry *entry);
42
43 /**
44  * Type of function for user defined matching.
45  *
46  * @param list
47  *   The hash list.
48  * @param entry
49  *   The entry in the list.
50  * @param key
51  *   The new entry key.
52  * @param ctx
53  *   The pointer to new entry context.
54  *
55  * @return
56  *   0 if matching, non-zero number otherwise.
57  */
58 typedef int (*mlx5_hlist_match_cb)(struct mlx5_hlist *list,
59                                    struct mlx5_hlist_entry *entry,
60                                    uint64_t key, void *ctx);
61
62 /**
63  * Type of function for user defined hash list entry creation.
64  *
65  * @param list
66  *   The hash list.
67  * @param key
68  *   The key of the new entry.
69  * @param ctx
70  *   The pointer to new entry context.
71  *
72  * @return
73  *   Pointer to allocated entry on success, NULL otherwise.
74  */
75 typedef struct mlx5_hlist_entry *(*mlx5_hlist_create_cb)
76                                   (struct mlx5_hlist *list,
77                                    uint64_t key, void *ctx);
78
79 /* Hash list bucket head. */
80 struct mlx5_hlist_bucket {
81         struct mlx5_hlist_head head; /* List head. */
82         rte_rwlock_t lock; /* Bucket lock. */
83         uint32_t gen_cnt; /* List modification will update generation count. */
84 } __rte_cache_aligned;
85
86 /**
87  * Hash list table structure
88  *
89  * Entry in hash list could be reused if entry already exists, reference
90  * count will increase and the existing entry returns.
91  *
92  * When destroy an entry from list, decrease reference count and only
93  * destroy when no further reference.
94  */
95 struct mlx5_hlist {
96         char name[MLX5_HLIST_NAMESIZE]; /**< Name of the hash list. */
97         /**< number of heads, need to be power of 2. */
98         uint32_t table_sz;
99         uint32_t entry_sz; /**< Size of entry, used to allocate entry. */
100         /**< mask to get the index of the list heads. */
101         uint32_t mask;
102         bool direct_key; /* Use the new entry key directly as hash index. */
103         bool write_most; /* List mostly used for append new or destroy. */
104         void *ctx;
105         mlx5_hlist_create_cb cb_create; /**< entry create callback. */
106         mlx5_hlist_match_cb cb_match; /**< entry match callback. */
107         mlx5_hlist_remove_cb cb_remove; /**< entry remove callback. */
108         struct mlx5_hlist_bucket buckets[] __rte_cache_aligned;
109         /**< list bucket arrays. */
110 };
111
112 /**
113  * Create a hash list table, the user can specify the list heads array size
114  * of the table, now the size should be a power of 2 in order to get better
115  * distribution for the entries. Each entry is a part of the whole data element
116  * and the caller should be responsible for the data element's allocation and
117  * cleanup / free. Key of each entry will be calculated with CRC in order to
118  * generate a little fairer distribution.
119  *
120  * @param name
121  *   Name of the hash list(optional).
122  * @param size
123  *   Heads array size of the hash list.
124  * @param entry_size
125  *   Entry size to allocate if cb_create not specified.
126  * @param flags
127  *   The hash list attribute flags.
128  * @param cb_create
129  *   Callback function for entry create.
130  * @param cb_match
131  *   Callback function for entry match.
132  * @param cb_destroy
133  *   Callback function for entry destroy.
134  * @return
135  *   Pointer of the hash list table created, NULL on failure.
136  */
137 __rte_internal
138 struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size,
139                                      uint32_t entry_size, uint32_t flags,
140                                      mlx5_hlist_create_cb cb_create,
141                                      mlx5_hlist_match_cb cb_match,
142                                      mlx5_hlist_remove_cb cb_destroy);
143
144 /**
145  * Search an entry matching the key.
146  *
147  * Result returned might be destroyed by other thread, must use
148  * this function only in main thread.
149  *
150  * @param h
151  *   Pointer to the hast list table.
152  * @param key
153  *   Key for the searching entry.
154  * @param ctx
155  *   Common context parameter used by entry callback function.
156  *
157  * @return
158  *   Pointer of the hlist entry if found, NULL otherwise.
159  */
160 __rte_internal
161 struct mlx5_hlist_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key,
162                                            void *ctx);
163
164 /**
165  * Insert an entry to the hash list table, the entry is only part of whole data
166  * element and a 64B key is used for matching. User should construct the key or
167  * give a calculated hash signature and guarantee there is no collision.
168  *
169  * @param h
170  *   Pointer to the hast list table.
171  * @param entry
172  *   Entry to be inserted into the hash list table.
173  * @param ctx
174  *   Common context parameter used by callback function.
175  *
176  * @return
177  *   registered entry on success, NULL otherwise
178  */
179 __rte_internal
180 struct mlx5_hlist_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key,
181                                              void *ctx);
182
183 /**
184  * Remove an entry from the hash list table. User should guarantee the validity
185  * of the entry.
186  *
187  * @param h
188  *   Pointer to the hast list table. (not used)
189  * @param entry
190  *   Entry to be removed from the hash list table.
191  * @return
192  *   0 on entry removed, 1 on entry still referenced.
193  */
194 __rte_internal
195 int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry);
196
197 /**
198  * Destroy the hash list table, all the entries already inserted into the lists
199  * will be handled by the callback function provided by the user (including
200  * free if needed) before the table is freed.
201  *
202  * @param h
203  *   Pointer to the hast list table.
204  */
205 __rte_internal
206 void mlx5_hlist_destroy(struct mlx5_hlist *h);
207
208 #endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */