xref: /dpdk/lib/member/rte_member.c (revision bbbe38a6d59ccdda25917712701e629d0b10af6f)
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.h>
9 #include <rte_eal_memconfig.h>
10 #include <rte_memory.h>
11 #include <rte_malloc.h>
12 #include <rte_errno.h>
13 #include <rte_tailq.h>
14 
15 #include "rte_member.h"
16 #include "rte_member_ht.h"
17 #include "rte_member_vbf.h"
18 
19 TAILQ_HEAD(rte_member_list, rte_tailq_entry);
20 static struct rte_tailq_elem rte_member_tailq = {
21 	.name = "RTE_MEMBER",
22 };
23 EAL_REGISTER_TAILQ(rte_member_tailq)
24 
25 struct rte_member_setsum *
26 rte_member_find_existing(const char *name)
27 {
28 	struct rte_member_setsum *setsum = NULL;
29 	struct rte_tailq_entry *te;
30 	struct rte_member_list *member_list;
31 
32 	member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
33 
34 	rte_mcfg_tailq_read_lock();
35 	TAILQ_FOREACH(te, member_list, next) {
36 		setsum = (struct rte_member_setsum *) te->data;
37 		if (strncmp(name, setsum->name, RTE_MEMBER_NAMESIZE) == 0)
38 			break;
39 	}
40 	rte_mcfg_tailq_read_unlock();
41 
42 	if (te == NULL) {
43 		rte_errno = ENOENT;
44 		return NULL;
45 	}
46 	return setsum;
47 }
48 
49 void
50 rte_member_free(struct rte_member_setsum *setsum)
51 {
52 	struct rte_member_list *member_list;
53 	struct rte_tailq_entry *te;
54 
55 	if (setsum == NULL)
56 		return;
57 	member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
58 	rte_mcfg_tailq_write_lock();
59 	TAILQ_FOREACH(te, member_list, next) {
60 		if (te->data == (void *)setsum)
61 			break;
62 	}
63 	if (te == NULL) {
64 		rte_mcfg_tailq_write_unlock();
65 		return;
66 	}
67 	TAILQ_REMOVE(member_list, te, next);
68 	rte_mcfg_tailq_write_unlock();
69 
70 	switch (setsum->type) {
71 	case RTE_MEMBER_TYPE_HT:
72 		rte_member_free_ht(setsum);
73 		break;
74 	case RTE_MEMBER_TYPE_VBF:
75 		rte_member_free_vbf(setsum);
76 		break;
77 	default:
78 		break;
79 	}
80 	rte_free(setsum);
81 	rte_free(te);
82 }
83 
84 struct rte_member_setsum *
85 rte_member_create(const struct rte_member_parameters *params)
86 {
87 	struct rte_tailq_entry *te;
88 	struct rte_member_list *member_list;
89 	struct rte_member_setsum *setsum;
90 	int ret;
91 
92 	if (params == NULL) {
93 		rte_errno = EINVAL;
94 		return NULL;
95 	}
96 
97 	if (params->key_len == 0 ||
98 			params->prim_hash_seed == params->sec_hash_seed) {
99 		rte_errno = EINVAL;
100 		RTE_MEMBER_LOG(ERR, "Create setsummary with "
101 					"invalid parameters\n");
102 		return NULL;
103 	}
104 
105 	member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
106 
107 	rte_mcfg_tailq_write_lock();
108 
109 	TAILQ_FOREACH(te, member_list, next) {
110 		setsum = te->data;
111 		if (strncmp(params->name, setsum->name,
112 				RTE_MEMBER_NAMESIZE) == 0)
113 			break;
114 	}
115 	setsum = NULL;
116 	if (te != NULL) {
117 		rte_errno = EEXIST;
118 		te = NULL;
119 		goto error_unlock_exit;
120 	}
121 	te = rte_zmalloc("MEMBER_TAILQ_ENTRY", sizeof(*te), 0);
122 	if (te == NULL) {
123 		RTE_MEMBER_LOG(ERR, "tailq entry allocation failed\n");
124 		goto error_unlock_exit;
125 	}
126 
127 	/* Create a new setsum structure */
128 	setsum = rte_zmalloc_socket(params->name,
129 			sizeof(struct rte_member_setsum), RTE_CACHE_LINE_SIZE,
130 			params->socket_id);
131 	if (setsum == NULL) {
132 		RTE_MEMBER_LOG(ERR, "Create setsummary failed\n");
133 		goto error_unlock_exit;
134 	}
135 	strlcpy(setsum->name, params->name, sizeof(setsum->name));
136 	setsum->type = params->type;
137 	setsum->socket_id = params->socket_id;
138 	setsum->key_len = params->key_len;
139 	setsum->num_set = params->num_set;
140 	setsum->prim_hash_seed = params->prim_hash_seed;
141 	setsum->sec_hash_seed = params->sec_hash_seed;
142 
143 	switch (setsum->type) {
144 	case RTE_MEMBER_TYPE_HT:
145 		ret = rte_member_create_ht(setsum, params);
146 		break;
147 	case RTE_MEMBER_TYPE_VBF:
148 		ret = rte_member_create_vbf(setsum, params);
149 		break;
150 	default:
151 		goto error_unlock_exit;
152 	}
153 	if (ret < 0)
154 		goto error_unlock_exit;
155 
156 	RTE_MEMBER_LOG(DEBUG, "Creating a setsummary table with "
157 			"mode %u\n", setsum->type);
158 
159 	te->data = (void *)setsum;
160 	TAILQ_INSERT_TAIL(member_list, te, next);
161 	rte_mcfg_tailq_write_unlock();
162 	return setsum;
163 
164 error_unlock_exit:
165 	rte_free(te);
166 	rte_free(setsum);
167 	rte_mcfg_tailq_write_unlock();
168 	return NULL;
169 }
170 
171 int
172 rte_member_add(const struct rte_member_setsum *setsum, const void *key,
173 			member_set_t set_id)
174 {
175 	if (setsum == NULL || key == NULL)
176 		return -EINVAL;
177 
178 	switch (setsum->type) {
179 	case RTE_MEMBER_TYPE_HT:
180 		return rte_member_add_ht(setsum, key, set_id);
181 	case RTE_MEMBER_TYPE_VBF:
182 		return rte_member_add_vbf(setsum, key, set_id);
183 	default:
184 		return -EINVAL;
185 	}
186 }
187 
188 int
189 rte_member_lookup(const struct rte_member_setsum *setsum, const void *key,
190 			member_set_t *set_id)
191 {
192 	if (setsum == NULL || key == NULL || set_id == NULL)
193 		return -EINVAL;
194 
195 	switch (setsum->type) {
196 	case RTE_MEMBER_TYPE_HT:
197 		return rte_member_lookup_ht(setsum, key, set_id);
198 	case RTE_MEMBER_TYPE_VBF:
199 		return rte_member_lookup_vbf(setsum, key, set_id);
200 	default:
201 		return -EINVAL;
202 	}
203 }
204 
205 int
206 rte_member_lookup_bulk(const struct rte_member_setsum *setsum,
207 				const void **keys, uint32_t num_keys,
208 				member_set_t *set_ids)
209 {
210 	if (setsum == NULL || keys == NULL || set_ids == NULL)
211 		return -EINVAL;
212 
213 	switch (setsum->type) {
214 	case RTE_MEMBER_TYPE_HT:
215 		return rte_member_lookup_bulk_ht(setsum, keys, num_keys,
216 				set_ids);
217 	case RTE_MEMBER_TYPE_VBF:
218 		return rte_member_lookup_bulk_vbf(setsum, keys, num_keys,
219 				set_ids);
220 	default:
221 		return -EINVAL;
222 	}
223 }
224 
225 int
226 rte_member_lookup_multi(const struct rte_member_setsum *setsum, const void *key,
227 				uint32_t match_per_key, 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_multi_ht(setsum, key, match_per_key,
235 				set_id);
236 	case RTE_MEMBER_TYPE_VBF:
237 		return rte_member_lookup_multi_vbf(setsum, key, match_per_key,
238 				set_id);
239 	default:
240 		return -EINVAL;
241 	}
242 }
243 
244 int
245 rte_member_lookup_multi_bulk(const struct rte_member_setsum *setsum,
246 			const void **keys, uint32_t num_keys,
247 			uint32_t max_match_per_key, uint32_t *match_count,
248 			member_set_t *set_ids)
249 {
250 	if (setsum == NULL || keys == NULL || set_ids == NULL ||
251 			match_count == NULL)
252 		return -EINVAL;
253 
254 	switch (setsum->type) {
255 	case RTE_MEMBER_TYPE_HT:
256 		return rte_member_lookup_multi_bulk_ht(setsum, keys, num_keys,
257 				max_match_per_key, match_count, set_ids);
258 	case RTE_MEMBER_TYPE_VBF:
259 		return rte_member_lookup_multi_bulk_vbf(setsum, keys, num_keys,
260 				max_match_per_key, match_count, set_ids);
261 	default:
262 		return -EINVAL;
263 	}
264 }
265 
266 int
267 rte_member_delete(const struct rte_member_setsum *setsum, const void *key,
268 			member_set_t set_id)
269 {
270 	if (setsum == NULL || key == NULL)
271 		return -EINVAL;
272 
273 	switch (setsum->type) {
274 	case RTE_MEMBER_TYPE_HT:
275 		return rte_member_delete_ht(setsum, key, set_id);
276 	/* current vBF implementation does not support delete function */
277 	case RTE_MEMBER_TYPE_VBF:
278 	default:
279 		return -EINVAL;
280 	}
281 }
282 
283 void
284 rte_member_reset(const struct rte_member_setsum *setsum)
285 {
286 	if (setsum == NULL)
287 		return;
288 	switch (setsum->type) {
289 	case RTE_MEMBER_TYPE_HT:
290 		rte_member_reset_ht(setsum);
291 		return;
292 	case RTE_MEMBER_TYPE_VBF:
293 		rte_member_reset_vbf(setsum);
294 		return;
295 	default:
296 		return;
297 	}
298 }
299 
300 RTE_LOG_REGISTER_DEFAULT(librte_member_logtype, DEBUG);
301