]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2017 Intel Corporation | |
3 | */ | |
4 | ||
5 | #include <string.h> | |
6 | ||
9f95a23c | 7 | #include <rte_string_fns.h> |
11fdf7f2 TL |
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 | ||
14 | #include "rte_member.h" | |
15 | #include "rte_member_ht.h" | |
16 | #include "rte_member_vbf.h" | |
17 | ||
18 | int librte_member_logtype; | |
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_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK); | |
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_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK); | |
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_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); | |
60 | TAILQ_FOREACH(te, member_list, next) { | |
61 | if (te->data == (void *)setsum) | |
62 | break; | |
63 | } | |
64 | if (te == NULL) { | |
65 | rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); | |
66 | return; | |
67 | } | |
68 | TAILQ_REMOVE(member_list, te, next); | |
69 | rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); | |
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 | default: | |
79 | break; | |
80 | } | |
81 | rte_free(setsum); | |
82 | rte_free(te); | |
83 | } | |
84 | ||
85 | struct rte_member_setsum * | |
86 | rte_member_create(const struct rte_member_parameters *params) | |
87 | { | |
88 | struct rte_tailq_entry *te; | |
89 | struct rte_member_list *member_list; | |
90 | struct rte_member_setsum *setsum; | |
91 | int ret; | |
92 | ||
93 | if (params == NULL) { | |
94 | rte_errno = EINVAL; | |
95 | return NULL; | |
96 | } | |
97 | ||
98 | if (params->key_len == 0 || | |
99 | params->prim_hash_seed == params->sec_hash_seed) { | |
100 | rte_errno = EINVAL; | |
101 | RTE_MEMBER_LOG(ERR, "Create setsummary with " | |
102 | "invalid parameters\n"); | |
103 | return NULL; | |
104 | } | |
105 | ||
106 | member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list); | |
107 | ||
108 | rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); | |
109 | ||
110 | TAILQ_FOREACH(te, member_list, next) { | |
111 | setsum = te->data; | |
112 | if (strncmp(params->name, setsum->name, | |
113 | RTE_MEMBER_NAMESIZE) == 0) | |
114 | break; | |
115 | } | |
116 | setsum = NULL; | |
117 | if (te != NULL) { | |
118 | rte_errno = EEXIST; | |
119 | te = NULL; | |
120 | goto error_unlock_exit; | |
121 | } | |
122 | te = rte_zmalloc("MEMBER_TAILQ_ENTRY", sizeof(*te), 0); | |
123 | if (te == NULL) { | |
124 | RTE_MEMBER_LOG(ERR, "tailq entry allocation failed\n"); | |
125 | goto error_unlock_exit; | |
126 | } | |
127 | ||
128 | /* Create a new setsum structure */ | |
129 | setsum = rte_zmalloc_socket(params->name, | |
130 | sizeof(struct rte_member_setsum), RTE_CACHE_LINE_SIZE, | |
131 | params->socket_id); | |
132 | if (setsum == NULL) { | |
133 | RTE_MEMBER_LOG(ERR, "Create setsummary failed\n"); | |
134 | goto error_unlock_exit; | |
135 | } | |
9f95a23c | 136 | strlcpy(setsum->name, params->name, sizeof(setsum->name)); |
11fdf7f2 TL |
137 | setsum->type = params->type; |
138 | setsum->socket_id = params->socket_id; | |
139 | setsum->key_len = params->key_len; | |
140 | setsum->num_set = params->num_set; | |
141 | setsum->prim_hash_seed = params->prim_hash_seed; | |
142 | setsum->sec_hash_seed = params->sec_hash_seed; | |
143 | ||
144 | switch (setsum->type) { | |
145 | case RTE_MEMBER_TYPE_HT: | |
146 | ret = rte_member_create_ht(setsum, params); | |
147 | break; | |
148 | case RTE_MEMBER_TYPE_VBF: | |
149 | ret = rte_member_create_vbf(setsum, params); | |
150 | break; | |
151 | default: | |
152 | goto error_unlock_exit; | |
153 | } | |
154 | if (ret < 0) | |
155 | goto error_unlock_exit; | |
156 | ||
157 | RTE_MEMBER_LOG(DEBUG, "Creating a setsummary table with " | |
158 | "mode %u\n", setsum->type); | |
159 | ||
160 | te->data = (void *)setsum; | |
161 | TAILQ_INSERT_TAIL(member_list, te, next); | |
162 | rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); | |
163 | return setsum; | |
164 | ||
165 | error_unlock_exit: | |
166 | rte_free(te); | |
167 | rte_free(setsum); | |
168 | rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); | |
169 | return NULL; | |
170 | } | |
171 | ||
172 | int | |
173 | rte_member_add(const struct rte_member_setsum *setsum, const void *key, | |
174 | member_set_t set_id) | |
175 | { | |
176 | if (setsum == NULL || key == NULL) | |
177 | return -EINVAL; | |
178 | ||
179 | switch (setsum->type) { | |
180 | case RTE_MEMBER_TYPE_HT: | |
181 | return rte_member_add_ht(setsum, key, set_id); | |
182 | case RTE_MEMBER_TYPE_VBF: | |
183 | return rte_member_add_vbf(setsum, key, set_id); | |
184 | default: | |
185 | return -EINVAL; | |
186 | } | |
187 | } | |
188 | ||
189 | int | |
190 | rte_member_lookup(const struct rte_member_setsum *setsum, const void *key, | |
191 | member_set_t *set_id) | |
192 | { | |
193 | if (setsum == NULL || key == NULL || set_id == NULL) | |
194 | return -EINVAL; | |
195 | ||
196 | switch (setsum->type) { | |
197 | case RTE_MEMBER_TYPE_HT: | |
198 | return rte_member_lookup_ht(setsum, key, set_id); | |
199 | case RTE_MEMBER_TYPE_VBF: | |
200 | return rte_member_lookup_vbf(setsum, key, set_id); | |
201 | default: | |
202 | return -EINVAL; | |
203 | } | |
204 | } | |
205 | ||
206 | int | |
207 | rte_member_lookup_bulk(const struct rte_member_setsum *setsum, | |
208 | const void **keys, uint32_t num_keys, | |
209 | member_set_t *set_ids) | |
210 | { | |
211 | if (setsum == NULL || keys == NULL || set_ids == NULL) | |
212 | return -EINVAL; | |
213 | ||
214 | switch (setsum->type) { | |
215 | case RTE_MEMBER_TYPE_HT: | |
216 | return rte_member_lookup_bulk_ht(setsum, keys, num_keys, | |
217 | set_ids); | |
218 | case RTE_MEMBER_TYPE_VBF: | |
219 | return rte_member_lookup_bulk_vbf(setsum, keys, num_keys, | |
220 | set_ids); | |
221 | default: | |
222 | return -EINVAL; | |
223 | } | |
224 | } | |
225 | ||
226 | int | |
227 | rte_member_lookup_multi(const struct rte_member_setsum *setsum, const void *key, | |
228 | uint32_t match_per_key, member_set_t *set_id) | |
229 | { | |
230 | if (setsum == NULL || key == NULL || set_id == NULL) | |
231 | return -EINVAL; | |
232 | ||
233 | switch (setsum->type) { | |
234 | case RTE_MEMBER_TYPE_HT: | |
235 | return rte_member_lookup_multi_ht(setsum, key, match_per_key, | |
236 | set_id); | |
237 | case RTE_MEMBER_TYPE_VBF: | |
238 | return rte_member_lookup_multi_vbf(setsum, key, match_per_key, | |
239 | set_id); | |
240 | default: | |
241 | return -EINVAL; | |
242 | } | |
243 | } | |
244 | ||
245 | int | |
246 | rte_member_lookup_multi_bulk(const struct rte_member_setsum *setsum, | |
247 | const void **keys, uint32_t num_keys, | |
248 | uint32_t max_match_per_key, uint32_t *match_count, | |
249 | member_set_t *set_ids) | |
250 | { | |
251 | if (setsum == NULL || keys == NULL || set_ids == NULL || | |
252 | match_count == NULL) | |
253 | return -EINVAL; | |
254 | ||
255 | switch (setsum->type) { | |
256 | case RTE_MEMBER_TYPE_HT: | |
257 | return rte_member_lookup_multi_bulk_ht(setsum, keys, num_keys, | |
258 | max_match_per_key, match_count, set_ids); | |
259 | case RTE_MEMBER_TYPE_VBF: | |
260 | return rte_member_lookup_multi_bulk_vbf(setsum, keys, num_keys, | |
261 | max_match_per_key, match_count, set_ids); | |
262 | default: | |
263 | return -EINVAL; | |
264 | } | |
265 | } | |
266 | ||
267 | int | |
268 | rte_member_delete(const struct rte_member_setsum *setsum, const void *key, | |
269 | member_set_t set_id) | |
270 | { | |
271 | if (setsum == NULL || key == NULL) | |
272 | return -EINVAL; | |
273 | ||
274 | switch (setsum->type) { | |
275 | case RTE_MEMBER_TYPE_HT: | |
276 | return rte_member_delete_ht(setsum, key, set_id); | |
277 | /* current vBF implementation does not support delete function */ | |
278 | case RTE_MEMBER_TYPE_VBF: | |
279 | default: | |
280 | return -EINVAL; | |
281 | } | |
282 | } | |
283 | ||
284 | void | |
285 | rte_member_reset(const struct rte_member_setsum *setsum) | |
286 | { | |
287 | if (setsum == NULL) | |
288 | return; | |
289 | switch (setsum->type) { | |
290 | case RTE_MEMBER_TYPE_HT: | |
291 | rte_member_reset_ht(setsum); | |
292 | return; | |
293 | case RTE_MEMBER_TYPE_VBF: | |
294 | rte_member_reset_vbf(setsum); | |
295 | return; | |
296 | default: | |
297 | return; | |
298 | } | |
299 | } | |
300 | ||
301 | RTE_INIT(librte_member_init_log) | |
302 | { | |
303 | librte_member_logtype = rte_log_register("lib.member"); | |
304 | if (librte_member_logtype >= 0) | |
305 | rte_log_set_level(librte_member_logtype, RTE_LOG_DEBUG); | |
306 | } |