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