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