1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Intel Corporation
3 */
4
5 #include <string.h>
6
7 #include <rte_string_fns.h>
8 #include <rte_eal_memconfig.h>
9 #include <rte_malloc.h>
10 #include <rte_errno.h>
11 #include <rte_tailq.h>
12 #include <rte_ring_elem.h>
13
14 #include "member.h"
15 #include "rte_member.h"
16 #include "rte_member_ht.h"
17 #include "rte_member_vbf.h"
18 #include "rte_member_sketch.h"
19
20 TAILQ_HEAD(rte_member_list, rte_tailq_entry);
21 static struct rte_tailq_elem rte_member_tailq = {
22 .name = "RTE_MEMBER",
23 };
EAL_REGISTER_TAILQ(rte_member_tailq)24 EAL_REGISTER_TAILQ(rte_member_tailq)
25
26 struct rte_member_setsum *
27 rte_member_find_existing(const char *name)
28 {
29 struct rte_member_setsum *setsum = NULL;
30 struct rte_tailq_entry *te;
31 struct rte_member_list *member_list;
32
33 member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
34
35 rte_mcfg_tailq_read_lock();
36 TAILQ_FOREACH(te, member_list, next) {
37 setsum = (struct rte_member_setsum *) te->data;
38 if (strncmp(name, setsum->name, RTE_MEMBER_NAMESIZE) == 0)
39 break;
40 }
41 rte_mcfg_tailq_read_unlock();
42
43 if (te == NULL) {
44 rte_errno = ENOENT;
45 return NULL;
46 }
47 return setsum;
48 }
49
50 void
rte_member_free(struct rte_member_setsum * setsum)51 rte_member_free(struct rte_member_setsum *setsum)
52 {
53 struct rte_member_list *member_list;
54 struct rte_tailq_entry *te;
55
56 if (setsum == NULL)
57 return;
58 member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
59 rte_mcfg_tailq_write_lock();
60 TAILQ_FOREACH(te, member_list, next) {
61 if (te->data == (void *)setsum)
62 break;
63 }
64 if (te == NULL) {
65 rte_mcfg_tailq_write_unlock();
66 return;
67 }
68 TAILQ_REMOVE(member_list, te, next);
69 rte_mcfg_tailq_write_unlock();
70
71 switch (setsum->type) {
72 case RTE_MEMBER_TYPE_HT:
73 rte_member_free_ht(setsum);
74 break;
75 case RTE_MEMBER_TYPE_VBF:
76 rte_member_free_vbf(setsum);
77 break;
78 case RTE_MEMBER_TYPE_SKETCH:
79 rte_member_free_sketch(setsum);
80 break;
81 default:
82 break;
83 }
84 rte_free(setsum);
85 rte_free(te);
86 }
87
88 struct rte_member_setsum *
rte_member_create(const struct rte_member_parameters * params)89 rte_member_create(const struct rte_member_parameters *params)
90 {
91 struct rte_tailq_entry *te;
92 struct rte_member_list *member_list;
93 struct rte_member_setsum *setsum;
94 int ret;
95 char ring_name[RTE_RING_NAMESIZE];
96 struct rte_ring *sketch_key_ring = NULL;
97
98 if (params == NULL) {
99 rte_errno = EINVAL;
100 return NULL;
101 }
102
103 if (params->key_len == 0 ||
104 params->prim_hash_seed == params->sec_hash_seed) {
105 rte_errno = EINVAL;
106 MEMBER_LOG(ERR, "Create setsummary with "
107 "invalid parameters");
108 return NULL;
109 }
110
111 if (params->type == RTE_MEMBER_TYPE_SKETCH) {
112 snprintf(ring_name, sizeof(ring_name), "SK_%s", params->name);
113 sketch_key_ring = rte_ring_create_elem(ring_name, sizeof(uint32_t),
114 rte_align32pow2(params->top_k), params->socket_id, 0);
115 if (sketch_key_ring == NULL) {
116 MEMBER_LOG(ERR, "Sketch Ring Memory allocation failed");
117 return NULL;
118 }
119 }
120
121 member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
122
123 rte_mcfg_tailq_write_lock();
124
125 TAILQ_FOREACH(te, member_list, next) {
126 setsum = te->data;
127 if (strncmp(params->name, setsum->name,
128 RTE_MEMBER_NAMESIZE) == 0)
129 break;
130 }
131 setsum = NULL;
132 if (te != NULL) {
133 rte_errno = EEXIST;
134 te = NULL;
135 goto error_unlock_exit;
136 }
137 te = rte_zmalloc("MEMBER_TAILQ_ENTRY", sizeof(*te), 0);
138 if (te == NULL) {
139 MEMBER_LOG(ERR, "tailq entry allocation failed");
140 goto error_unlock_exit;
141 }
142
143 /* Create a new setsum structure */
144 setsum = rte_zmalloc_socket(params->name,
145 sizeof(struct rte_member_setsum), RTE_CACHE_LINE_SIZE,
146 params->socket_id);
147 if (setsum == NULL) {
148 MEMBER_LOG(ERR, "Create setsummary failed");
149 goto error_unlock_exit;
150 }
151 strlcpy(setsum->name, params->name, sizeof(setsum->name));
152 setsum->type = params->type;
153 setsum->socket_id = params->socket_id;
154 setsum->key_len = params->key_len;
155 setsum->num_set = params->num_set;
156 setsum->prim_hash_seed = params->prim_hash_seed;
157 setsum->sec_hash_seed = params->sec_hash_seed;
158
159 switch (setsum->type) {
160 case RTE_MEMBER_TYPE_HT:
161 ret = rte_member_create_ht(setsum, params);
162 break;
163 case RTE_MEMBER_TYPE_VBF:
164 ret = rte_member_create_vbf(setsum, params);
165 break;
166 case RTE_MEMBER_TYPE_SKETCH:
167 ret = rte_member_create_sketch(setsum, params, sketch_key_ring);
168 break;
169 default:
170 goto error_unlock_exit;
171 }
172 if (ret < 0)
173 goto error_unlock_exit;
174
175 MEMBER_LOG(DEBUG, "Creating a setsummary table with "
176 "mode %u", setsum->type);
177
178 te->data = (void *)setsum;
179 TAILQ_INSERT_TAIL(member_list, te, next);
180 rte_mcfg_tailq_write_unlock();
181 return setsum;
182
183 error_unlock_exit:
184 rte_free(te);
185 rte_free(setsum);
186 rte_ring_free(sketch_key_ring);
187 rte_mcfg_tailq_write_unlock();
188 return NULL;
189 }
190
191 int
rte_member_add(const struct rte_member_setsum * setsum,const void * key,member_set_t set_id)192 rte_member_add(const struct rte_member_setsum *setsum, const void *key,
193 member_set_t set_id)
194 {
195 if (setsum == NULL || key == NULL)
196 return -EINVAL;
197
198 switch (setsum->type) {
199 case RTE_MEMBER_TYPE_HT:
200 return rte_member_add_ht(setsum, key, set_id);
201 case RTE_MEMBER_TYPE_VBF:
202 return rte_member_add_vbf(setsum, key, set_id);
203 case RTE_MEMBER_TYPE_SKETCH:
204 return rte_member_add_sketch(setsum, key, set_id);
205 default:
206 return -EINVAL;
207 }
208 }
209
210 int
rte_member_add_byte_count(const struct rte_member_setsum * setsum,const void * key,uint32_t byte_count)211 rte_member_add_byte_count(const struct rte_member_setsum *setsum,
212 const void *key, uint32_t byte_count)
213 {
214 if (setsum == NULL || key == NULL || byte_count == 0)
215 return -EINVAL;
216
217 switch (setsum->type) {
218 case RTE_MEMBER_TYPE_SKETCH:
219 return rte_member_add_sketch_byte_count(setsum, key, byte_count);
220 default:
221 return -EINVAL;
222 }
223 }
224
225 int
rte_member_lookup(const struct rte_member_setsum * setsum,const void * key,member_set_t * set_id)226 rte_member_lookup(const struct rte_member_setsum *setsum, const void *key,
227 member_set_t *set_id)
228 {
229 if (setsum == NULL || key == NULL || set_id == NULL)
230 return -EINVAL;
231
232 switch (setsum->type) {
233 case RTE_MEMBER_TYPE_HT:
234 return rte_member_lookup_ht(setsum, key, set_id);
235 case RTE_MEMBER_TYPE_VBF:
236 return rte_member_lookup_vbf(setsum, key, set_id);
237 case RTE_MEMBER_TYPE_SKETCH:
238 return rte_member_lookup_sketch(setsum, key, set_id);
239 default:
240 return -EINVAL;
241 }
242 }
243
244 int
rte_member_lookup_bulk(const struct rte_member_setsum * setsum,const void ** keys,uint32_t num_keys,member_set_t * set_ids)245 rte_member_lookup_bulk(const struct rte_member_setsum *setsum,
246 const void **keys, uint32_t num_keys,
247 member_set_t *set_ids)
248 {
249 if (setsum == NULL || keys == NULL || set_ids == NULL)
250 return -EINVAL;
251
252 switch (setsum->type) {
253 case RTE_MEMBER_TYPE_HT:
254 return rte_member_lookup_bulk_ht(setsum, keys, num_keys,
255 set_ids);
256 case RTE_MEMBER_TYPE_VBF:
257 return rte_member_lookup_bulk_vbf(setsum, keys, num_keys,
258 set_ids);
259 default:
260 return -EINVAL;
261 }
262 }
263
264 int
rte_member_lookup_multi(const struct rte_member_setsum * setsum,const void * key,uint32_t match_per_key,member_set_t * set_id)265 rte_member_lookup_multi(const struct rte_member_setsum *setsum, const void *key,
266 uint32_t match_per_key, member_set_t *set_id)
267 {
268 if (setsum == NULL || key == NULL || set_id == NULL)
269 return -EINVAL;
270
271 switch (setsum->type) {
272 case RTE_MEMBER_TYPE_HT:
273 return rte_member_lookup_multi_ht(setsum, key, match_per_key,
274 set_id);
275 case RTE_MEMBER_TYPE_VBF:
276 return rte_member_lookup_multi_vbf(setsum, key, match_per_key,
277 set_id);
278 default:
279 return -EINVAL;
280 }
281 }
282
283 int
rte_member_lookup_multi_bulk(const struct rte_member_setsum * setsum,const void ** keys,uint32_t num_keys,uint32_t max_match_per_key,uint32_t * match_count,member_set_t * set_ids)284 rte_member_lookup_multi_bulk(const struct rte_member_setsum *setsum,
285 const void **keys, uint32_t num_keys,
286 uint32_t max_match_per_key, uint32_t *match_count,
287 member_set_t *set_ids)
288 {
289 if (setsum == NULL || keys == NULL || set_ids == NULL ||
290 match_count == NULL)
291 return -EINVAL;
292
293 switch (setsum->type) {
294 case RTE_MEMBER_TYPE_HT:
295 return rte_member_lookup_multi_bulk_ht(setsum, keys, num_keys,
296 max_match_per_key, match_count, set_ids);
297 case RTE_MEMBER_TYPE_VBF:
298 return rte_member_lookup_multi_bulk_vbf(setsum, keys, num_keys,
299 max_match_per_key, match_count, set_ids);
300 default:
301 return -EINVAL;
302 }
303 }
304
305 int
rte_member_query_count(const struct rte_member_setsum * setsum,const void * key,uint64_t * output)306 rte_member_query_count(const struct rte_member_setsum *setsum,
307 const void *key, uint64_t *output)
308 {
309 if (setsum == NULL || key == NULL || output == NULL)
310 return -EINVAL;
311
312 switch (setsum->type) {
313 case RTE_MEMBER_TYPE_SKETCH:
314 return rte_member_query_sketch(setsum, key, output);
315 default:
316 return -EINVAL;
317 }
318 }
319
320 int
rte_member_report_heavyhitter(const struct rte_member_setsum * setsum,void ** key,uint64_t * count)321 rte_member_report_heavyhitter(const struct rte_member_setsum *setsum,
322 void **key, uint64_t *count)
323 {
324 if (setsum == NULL || key == NULL || count == NULL)
325 return -EINVAL;
326
327 switch (setsum->type) {
328 case RTE_MEMBER_TYPE_SKETCH:
329 return rte_member_report_heavyhitter_sketch(setsum, key, count);
330 default:
331 return -EINVAL;
332 }
333 }
334
335 int
rte_member_delete(const struct rte_member_setsum * setsum,const void * key,member_set_t set_id)336 rte_member_delete(const struct rte_member_setsum *setsum, const void *key,
337 member_set_t set_id)
338 {
339 if (setsum == NULL || key == NULL)
340 return -EINVAL;
341
342 switch (setsum->type) {
343 case RTE_MEMBER_TYPE_HT:
344 return rte_member_delete_ht(setsum, key, set_id);
345 /* current vBF implementation does not support delete function */
346 case RTE_MEMBER_TYPE_SKETCH:
347 return rte_member_delete_sketch(setsum, key);
348 case RTE_MEMBER_TYPE_VBF:
349 default:
350 return -EINVAL;
351 }
352 }
353
354 void
rte_member_reset(const struct rte_member_setsum * setsum)355 rte_member_reset(const struct rte_member_setsum *setsum)
356 {
357 if (setsum == NULL)
358 return;
359 switch (setsum->type) {
360 case RTE_MEMBER_TYPE_HT:
361 rte_member_reset_ht(setsum);
362 return;
363 case RTE_MEMBER_TYPE_VBF:
364 rte_member_reset_vbf(setsum);
365 return;
366 case RTE_MEMBER_TYPE_SKETCH:
367 rte_member_reset_sketch(setsum);
368 return;
369 default:
370 return;
371 }
372 }
373
374 RTE_LOG_REGISTER_DEFAULT(librte_member_logtype, DEBUG);
375