xref: /dpdk/lib/member/rte_member.c (revision 3da59f30a23f2e795d2315f3d949e1b3e0ce0c3d)
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 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
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 *
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
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
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
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
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
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
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
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
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
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
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