New upstream version 18.08
[deb_dpdk.git] / lib / librte_member / rte_member.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4
5 #include <string.h>
6
7 #include <rte_eal.h>
8 #include <rte_eal_memconfig.h>
9 #include <rte_memory.h>
10 #include <rte_malloc.h>
11 #include <rte_errno.h>
12
13 #include "rte_member.h"
14 #include "rte_member_ht.h"
15 #include "rte_member_vbf.h"
16
17 int librte_member_logtype;
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_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
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_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
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_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
59         TAILQ_FOREACH(te, member_list, next) {
60                 if (te->data == (void *)setsum)
61                         break;
62         }
63         if (te == NULL) {
64                 rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
65                 return;
66         }
67         TAILQ_REMOVE(member_list, te, next);
68         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
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_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
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         snprintf(setsum->name, sizeof(setsum->name), "%s", params->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_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
162         return setsum;
163
164 error_unlock_exit:
165         rte_free(te);
166         rte_free(setsum);
167         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
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_INIT(librte_member_init_log)
301 {
302         librte_member_logtype = rte_log_register("lib.member");
303         if (librte_member_logtype >= 0)
304                 rte_log_set_level(librte_member_logtype, RTE_LOG_DEBUG);
305 }