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