hash: fix memory allocation of cuckoo key table
[dpdk.git] / lib / librte_hash / rte_cuckoo_hash.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <string.h>
35 #include <stdint.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <sys/queue.h>
40
41 #include <rte_common.h>
42 #include <rte_memory.h>         /* for definition of RTE_CACHE_LINE_SIZE */
43 #include <rte_log.h>
44 #include <rte_memcpy.h>
45 #include <rte_prefetch.h>
46 #include <rte_branch_prediction.h>
47 #include <rte_memzone.h>
48 #include <rte_malloc.h>
49 #include <rte_eal.h>
50 #include <rte_eal_memconfig.h>
51 #include <rte_per_lcore.h>
52 #include <rte_errno.h>
53 #include <rte_string_fns.h>
54 #include <rte_cpuflags.h>
55 #include <rte_log.h>
56 #include <rte_rwlock.h>
57 #include <rte_spinlock.h>
58 #include <rte_ring.h>
59 #include <rte_compat.h>
60
61 #include "rte_hash.h"
62 #if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) || defined(RTE_ARCH_X86_X32)
63 #include "rte_cmp_x86.h"
64 #endif
65
66 TAILQ_HEAD(rte_hash_list, rte_tailq_entry);
67
68 static struct rte_tailq_elem rte_hash_tailq = {
69         .name = "RTE_HASH",
70 };
71 EAL_REGISTER_TAILQ(rte_hash_tailq)
72
73 /* Macro to enable/disable run-time checking of function parameters */
74 #if defined(RTE_LIBRTE_HASH_DEBUG)
75 #define RETURN_IF_TRUE(cond, retval) do { \
76         if (cond) \
77                 return retval; \
78 } while (0)
79 #else
80 #define RETURN_IF_TRUE(cond, retval)
81 #endif
82
83 /* Hash function used if none is specified */
84 #ifdef RTE_MACHINE_CPUFLAG_SSE4_2
85 #include <rte_hash_crc.h>
86 #define DEFAULT_HASH_FUNC       rte_hash_crc
87 #else
88 #include <rte_jhash.h>
89 #define DEFAULT_HASH_FUNC       rte_jhash
90 #endif
91
92 /** Number of items per bucket. */
93 #define RTE_HASH_BUCKET_ENTRIES         4
94
95 #define NULL_SIGNATURE                  0
96
97 #define KEY_ALIGNMENT                   16
98
99 typedef int (*rte_hash_cmp_eq_t)(const void *key1, const void *key2, size_t key_len);
100
101 /** A hash table structure. */
102 struct rte_hash {
103         char name[RTE_HASH_NAMESIZE];   /**< Name of the hash. */
104         uint32_t entries;               /**< Total table entries. */
105         uint32_t num_buckets;           /**< Number of buckets in table. */
106         uint32_t key_len;               /**< Length of hash key. */
107         rte_hash_function hash_func;    /**< Function used to calculate hash. */
108         uint32_t hash_func_init_val;    /**< Init value used by hash_func. */
109         rte_hash_cmp_eq_t rte_hash_cmp_eq; /**< Function used to compare keys. */
110         uint32_t bucket_bitmask;        /**< Bitmask for getting bucket index
111                                                 from hash signature. */
112         uint32_t key_entry_size;         /**< Size of each key entry. */
113
114         struct rte_ring *free_slots;    /**< Ring that stores all indexes
115                                                 of the free slots in the key table */
116         void *key_store;                /**< Table storing all keys and data */
117         struct rte_hash_bucket *buckets;        /**< Table with buckets storing all the
118                                                         hash values and key indexes
119                                                         to the key table*/
120 } __rte_cache_aligned;
121
122 /* Structure storing both primary and secondary hashes */
123 struct rte_hash_signatures {
124         union {
125                 struct {
126                         hash_sig_t current;
127                         hash_sig_t alt;
128                 };
129                 uint64_t sig;
130         };
131 };
132
133 /* Structure that stores key-value pair */
134 struct rte_hash_key {
135         union {
136                 uintptr_t idata;
137                 void *pdata;
138         };
139         /* Variable key size */
140         char key[0];
141 } __attribute__((aligned(KEY_ALIGNMENT)));
142
143 /** Bucket structure */
144 struct rte_hash_bucket {
145         struct rte_hash_signatures signatures[RTE_HASH_BUCKET_ENTRIES];
146         /* Includes dummy key index that always contains index 0 */
147         uint32_t key_idx[RTE_HASH_BUCKET_ENTRIES + 1];
148         uint8_t flag[RTE_HASH_BUCKET_ENTRIES];
149 } __rte_cache_aligned;
150
151 struct rte_hash *
152 rte_hash_find_existing(const char *name)
153 {
154         struct rte_hash *h = NULL;
155         struct rte_tailq_entry *te;
156         struct rte_hash_list *hash_list;
157
158         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
159
160         rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
161         TAILQ_FOREACH(te, hash_list, next) {
162                 h = (struct rte_hash *) te->data;
163                 if (strncmp(name, h->name, RTE_HASH_NAMESIZE) == 0)
164                         break;
165         }
166         rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
167
168         if (te == NULL) {
169                 rte_errno = ENOENT;
170                 return NULL;
171         }
172         return h;
173 }
174
175 struct rte_hash *
176 rte_hash_create(const struct rte_hash_parameters *params)
177 {
178         struct rte_hash *h = NULL;
179         struct rte_tailq_entry *te = NULL;
180         struct rte_hash_list *hash_list;
181         struct rte_ring *r = NULL;
182         char hash_name[RTE_HASH_NAMESIZE];
183         void *ptr, *k = NULL;
184         void *buckets = NULL;
185         char ring_name[RTE_RING_NAMESIZE];
186         unsigned i;
187
188         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
189
190         if (params == NULL) {
191                 RTE_LOG(ERR, HASH, "rte_hash_create has no parameters\n");
192                 return NULL;
193         }
194
195         /* Check for valid parameters */
196         if ((params->entries > RTE_HASH_ENTRIES_MAX) ||
197                         (params->entries < RTE_HASH_BUCKET_ENTRIES) ||
198                         !rte_is_power_of_2(RTE_HASH_BUCKET_ENTRIES) ||
199                         (params->key_len == 0)) {
200                 rte_errno = EINVAL;
201                 RTE_LOG(ERR, HASH, "rte_hash_create has invalid parameters\n");
202                 return NULL;
203         }
204
205         snprintf(hash_name, sizeof(hash_name), "HT_%s", params->name);
206
207         /* Guarantee there's no existing */
208         h = rte_hash_find_existing(params->name);
209         if (h != NULL)
210                 return h;
211
212         te = rte_zmalloc("HASH_TAILQ_ENTRY", sizeof(*te), 0);
213         if (te == NULL) {
214                 RTE_LOG(ERR, HASH, "tailq entry allocation failed\n");
215                 goto err;
216         }
217
218         h = (struct rte_hash *)rte_zmalloc_socket(hash_name, sizeof(struct rte_hash),
219                                         RTE_CACHE_LINE_SIZE, params->socket_id);
220
221         if (h == NULL) {
222                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
223                 goto err;
224         }
225
226         const uint32_t num_buckets = rte_align32pow2(params->entries)
227                                         / RTE_HASH_BUCKET_ENTRIES;
228
229         buckets = rte_zmalloc_socket(NULL,
230                                 num_buckets * sizeof(struct rte_hash_bucket),
231                                 RTE_CACHE_LINE_SIZE, params->socket_id);
232
233         if (buckets == NULL) {
234                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
235                 goto err;
236         }
237
238         const uint32_t key_entry_size = sizeof(struct rte_hash_key) + params->key_len;
239
240         /* Store all keys and leave the first entry as a dummy entry for lookup_bulk */
241         const uint64_t key_tbl_size = (uint64_t) key_entry_size * (params->entries + 1);
242
243         k = rte_zmalloc_socket(NULL, key_tbl_size,
244                         RTE_CACHE_LINE_SIZE, params->socket_id);
245
246         if (k == NULL) {
247                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
248                 goto err;
249         }
250
251 /*
252  * If x86 architecture is used, select appropriate compare function,
253  * which may use x86 instrinsics, otherwise use memcmp
254  */
255 #if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) || defined(RTE_ARCH_X86_X32)
256         /* Select function to compare keys */
257         switch (params->key_len) {
258         case 16:
259                 h->rte_hash_cmp_eq = rte_hash_k16_cmp_eq;
260                 break;
261         case 32:
262                 h->rte_hash_cmp_eq = rte_hash_k32_cmp_eq;
263                 break;
264         case 48:
265                 h->rte_hash_cmp_eq = rte_hash_k48_cmp_eq;
266                 break;
267         case 64:
268                 h->rte_hash_cmp_eq = rte_hash_k64_cmp_eq;
269                 break;
270         case 80:
271                 h->rte_hash_cmp_eq = rte_hash_k80_cmp_eq;
272                 break;
273         case 96:
274                 h->rte_hash_cmp_eq = rte_hash_k96_cmp_eq;
275                 break;
276         case 112:
277                 h->rte_hash_cmp_eq = rte_hash_k112_cmp_eq;
278                 break;
279         case 128:
280                 h->rte_hash_cmp_eq = rte_hash_k128_cmp_eq;
281                 break;
282         default:
283                 /* If key is not multiple of 16, use generic memcmp */
284                 h->rte_hash_cmp_eq = memcmp;
285         }
286 #else
287         h->rte_hash_cmp_eq = memcmp;
288 #endif
289
290         snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name);
291         r = rte_ring_lookup(ring_name);
292         if (r != NULL) {
293                 /* clear the free ring */
294                 while (rte_ring_dequeue(r, &ptr) == 0)
295                         rte_pause();
296         } else
297                 r = rte_ring_create(ring_name, rte_align32pow2(params->entries + 1),
298                                 params->socket_id, 0);
299         if (r == NULL) {
300                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
301                 goto err;
302         }
303
304         /* Setup hash context */
305         snprintf(h->name, sizeof(h->name), "%s", params->name);
306         h->entries = params->entries;
307         h->key_len = params->key_len;
308         h->key_entry_size = key_entry_size;
309         h->hash_func_init_val = params->hash_func_init_val;
310
311         h->num_buckets = num_buckets;
312         h->bucket_bitmask = h->num_buckets - 1;
313         h->buckets = buckets;
314         h->hash_func = (params->hash_func == NULL) ?
315                 DEFAULT_HASH_FUNC : params->hash_func;
316
317         h->key_store = k;
318         h->free_slots = r;
319
320         /* populate the free slots ring. Entry zero is reserved for key misses */
321         for (i = 1; i < params->entries + 1; i++)
322                 rte_ring_sp_enqueue(r, (void *)((uintptr_t) i));
323
324         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
325         te->data = (void *) h;
326         TAILQ_INSERT_TAIL(hash_list, te, next);
327         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
328
329         return h;
330 err:
331         rte_free(te);
332         rte_free(h);
333         rte_free(buckets);
334         rte_free(k);
335         return NULL;
336 }
337
338 void
339 rte_hash_free(struct rte_hash *h)
340 {
341         struct rte_tailq_entry *te;
342         struct rte_hash_list *hash_list;
343
344         if (h == NULL)
345                 return;
346
347         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
348
349         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
350
351         /* find out tailq entry */
352         TAILQ_FOREACH(te, hash_list, next) {
353                 if (te->data == (void *) h)
354                         break;
355         }
356
357         if (te == NULL) {
358                 rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
359                 return;
360         }
361
362         TAILQ_REMOVE(hash_list, te, next);
363
364         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
365
366         rte_free(h->key_store);
367         rte_free(h->buckets);
368         rte_free(h);
369         rte_free(te);
370 }
371
372 hash_sig_t
373 rte_hash_hash(const struct rte_hash *h, const void *key)
374 {
375         /* calc hash result by key */
376         return h->hash_func(key, h->key_len, h->hash_func_init_val);
377 }
378
379 /* Calc the secondary hash value from the primary hash value of a given key */
380 static inline hash_sig_t
381 rte_hash_secondary_hash(const hash_sig_t primary_hash)
382 {
383         static const unsigned all_bits_shift = 12;
384         static const unsigned alt_bits_xor = 0x5bd1e995;
385
386         uint32_t tag = primary_hash >> all_bits_shift;
387
388         return (primary_hash ^ ((tag + 1) * alt_bits_xor));
389 }
390
391 void
392 rte_hash_reset(struct rte_hash *h)
393 {
394         void *ptr;
395         unsigned i;
396
397         if (h == NULL)
398                 return;
399
400         memset(h->buckets, 0, h->num_buckets * sizeof(struct rte_hash_bucket));
401         memset(h->key_store, 0, h->key_entry_size * (h->entries + 1));
402
403         /* clear the free ring */
404         while (rte_ring_dequeue(h->free_slots, &ptr) == 0)
405                 rte_pause();
406
407         /* Repopulate the free slots ring. Entry zero is reserved for key misses */
408         for (i = 1; i < h->entries + 1; i++)
409                 rte_ring_sp_enqueue(h->free_slots, (void *)((uintptr_t) i));
410 }
411
412 /* Search for an entry that can be pushed to its alternative location */
413 static inline int
414 make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
415 {
416         unsigned i, j;
417         int ret;
418         uint32_t next_bucket_idx;
419         struct rte_hash_bucket *next_bkt[RTE_HASH_BUCKET_ENTRIES];
420
421         /*
422          * Push existing item (search for bucket with space in
423          * alternative locations) to its alternative location
424          */
425         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
426                 /* Search for space in alternative locations */
427                 next_bucket_idx = bkt->signatures[i].alt & h->bucket_bitmask;
428                 next_bkt[i] = &h->buckets[next_bucket_idx];
429                 for (j = 0; j < RTE_HASH_BUCKET_ENTRIES; j++) {
430                         if (next_bkt[i]->signatures[j].sig == NULL_SIGNATURE)
431                                 break;
432                 }
433
434                 if (j != RTE_HASH_BUCKET_ENTRIES)
435                         break;
436         }
437
438         /* Alternative location has spare room (end of recursive function) */
439         if (i != RTE_HASH_BUCKET_ENTRIES) {
440                 next_bkt[i]->signatures[j].alt = bkt->signatures[i].current;
441                 next_bkt[i]->signatures[j].current = bkt->signatures[i].alt;
442                 next_bkt[i]->key_idx[j] = bkt->key_idx[i];
443                 return i;
444         }
445
446         /* Pick entry that has not been pushed yet */
447         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++)
448                 if (bkt->flag[i] == 0)
449                         break;
450
451         /* All entries have been pushed, so entry cannot be added */
452         if (i == RTE_HASH_BUCKET_ENTRIES)
453                 return -ENOSPC;
454
455         /* Set flag to indicate that this entry is going to be pushed */
456         bkt->flag[i] = 1;
457         /* Need room in alternative bucket to insert the pushed entry */
458         ret = make_space_bucket(h, next_bkt[i]);
459         /*
460          * After recursive function.
461          * Clear flags and insert the pushed entry
462          * in its alternative location if successful,
463          * or return error
464          */
465         bkt->flag[i] = 0;
466         if (ret >= 0) {
467                 next_bkt[i]->signatures[ret].alt = bkt->signatures[i].current;
468                 next_bkt[i]->signatures[ret].current = bkt->signatures[i].alt;
469                 next_bkt[i]->key_idx[ret] = bkt->key_idx[i];
470                 return i;
471         } else
472                 return ret;
473
474 }
475
476 static inline int32_t
477 __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,
478                                                 hash_sig_t sig, void *data)
479 {
480         hash_sig_t alt_hash;
481         uint32_t prim_bucket_idx, sec_bucket_idx;
482         unsigned i;
483         struct rte_hash_bucket *prim_bkt, *sec_bkt;
484         struct rte_hash_key *new_k, *k, *keys = h->key_store;
485         void *slot_id;
486         uint32_t new_idx;
487         int ret;
488
489         prim_bucket_idx = sig & h->bucket_bitmask;
490         prim_bkt = &h->buckets[prim_bucket_idx];
491         rte_prefetch0(prim_bkt);
492
493         alt_hash = rte_hash_secondary_hash(sig);
494         sec_bucket_idx = alt_hash & h->bucket_bitmask;
495         sec_bkt = &h->buckets[sec_bucket_idx];
496         rte_prefetch0(sec_bkt);
497
498         /* Get a new slot for storing the new key */
499         if (rte_ring_sc_dequeue(h->free_slots, &slot_id) != 0)
500                 return -ENOSPC;
501         new_k = RTE_PTR_ADD(keys, (uintptr_t)slot_id * h->key_entry_size);
502         rte_prefetch0(new_k);
503         new_idx = (uint32_t)((uintptr_t) slot_id);
504
505         /* Check if key is already inserted in primary location */
506         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
507                 if (prim_bkt->signatures[i].current == sig &&
508                                 prim_bkt->signatures[i].alt == alt_hash)  {
509                         k = (struct rte_hash_key *) ((char *)keys +
510                                         prim_bkt->key_idx[i] * h->key_entry_size);
511                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
512                                 rte_ring_sp_enqueue(h->free_slots, slot_id);
513                                 /* Update data */
514                                 k->pdata = data;
515                                 /*
516                                  * Return index where key is stored,
517                                  * substracting the first dummy index
518                                  */
519                                 return (prim_bkt->key_idx[i] - 1);
520                         }
521                 }
522         }
523
524         /* Check if key is already inserted in secondary location */
525         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
526                 if (sec_bkt->signatures[i].alt == sig &&
527                                 sec_bkt->signatures[i].current == alt_hash)  {
528                         k = (struct rte_hash_key *) ((char *)keys +
529                                         sec_bkt->key_idx[i] * h->key_entry_size);
530                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
531                                 rte_ring_sp_enqueue(h->free_slots, slot_id);
532                                 /* Update data */
533                                 k->pdata = data;
534                                 /*
535                                  * Return index where key is stored,
536                                  * substracting the first dummy index
537                                  */
538                                 return (sec_bkt->key_idx[i] - 1);
539                         }
540                 }
541         }
542
543         /* Copy key */
544         rte_memcpy(new_k->key, key, h->key_len);
545         new_k->pdata = data;
546
547         /* Insert new entry is there is room in the primary bucket */
548         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
549                 /* Check if slot is available */
550                 if (likely(prim_bkt->signatures[i].sig == NULL_SIGNATURE)) {
551                         prim_bkt->signatures[i].current = sig;
552                         prim_bkt->signatures[i].alt = alt_hash;
553                         prim_bkt->key_idx[i] = new_idx;
554                         return new_idx - 1;
555                 }
556         }
557
558         /* Primary bucket is full, so we need to make space for new entry */
559         ret = make_space_bucket(h, prim_bkt);
560         /*
561          * After recursive function.
562          * Insert the new entry in the position of the pushed entry
563          * if successful or return error and
564          * store the new slot back in the ring
565          */
566         if (ret >= 0) {
567                 prim_bkt->signatures[ret].current = sig;
568                 prim_bkt->signatures[ret].alt = alt_hash;
569                 prim_bkt->key_idx[ret] = new_idx;
570                 return (new_idx - 1);
571         }
572
573         /* Error in addition, store new slot back in the ring and return error */
574         rte_ring_sp_enqueue(h->free_slots,
575                 (void *)((uintptr_t) new_idx));
576         return ret;
577
578 }
579
580 int32_t
581 rte_hash_add_key_with_hash(const struct rte_hash *h,
582                         const void *key, hash_sig_t sig)
583 {
584         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
585         return __rte_hash_add_key_with_hash(h, key, sig, 0);
586 }
587
588 int32_t
589 rte_hash_add_key(const struct rte_hash *h, const void *key)
590 {
591         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
592         return __rte_hash_add_key_with_hash(h, key, rte_hash_hash(h, key), 0);
593 }
594
595 int
596 rte_hash_add_key_with_hash_data(const struct rte_hash *h,
597                         const void *key, hash_sig_t sig, void *data)
598 {
599         int ret;
600
601         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
602         ret = __rte_hash_add_key_with_hash(h, key, sig, data);
603         if (ret >= 0)
604                 return 0;
605         else
606                 return ret;
607 }
608
609 int
610 rte_hash_add_key_data(const struct rte_hash *h, const void *key, void *data)
611 {
612         int ret;
613
614         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
615
616         ret = __rte_hash_add_key_with_hash(h, key, rte_hash_hash(h, key), data);
617         if (ret >= 0)
618                 return 0;
619         else
620                 return ret;
621 }
622 static inline int32_t
623 __rte_hash_lookup_with_hash(const struct rte_hash *h, const void *key,
624                                         hash_sig_t sig, void **data)
625 {
626         uint32_t bucket_idx;
627         hash_sig_t alt_hash;
628         unsigned i;
629         struct rte_hash_bucket *bkt;
630         struct rte_hash_key *k, *keys = h->key_store;
631
632         bucket_idx = sig & h->bucket_bitmask;
633         bkt = &h->buckets[bucket_idx];
634
635         /* Check if key is in primary location */
636         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
637                 if (bkt->signatures[i].current == sig &&
638                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
639                         k = (struct rte_hash_key *) ((char *)keys +
640                                         bkt->key_idx[i] * h->key_entry_size);
641                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
642                                 if (data != NULL)
643                                         *data = k->pdata;
644                                 /*
645                                  * Return index where key is stored,
646                                  * substracting the first dummy index
647                                  */
648                                 return (bkt->key_idx[i] - 1);
649                         }
650                 }
651         }
652
653         /* Calculate secondary hash */
654         alt_hash = rte_hash_secondary_hash(sig);
655         bucket_idx = alt_hash & h->bucket_bitmask;
656         bkt = &h->buckets[bucket_idx];
657
658         /* Check if key is in secondary location */
659         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
660                 if (bkt->signatures[i].current == alt_hash &&
661                                 bkt->signatures[i].alt == sig) {
662                         k = (struct rte_hash_key *) ((char *)keys +
663                                         bkt->key_idx[i] * h->key_entry_size);
664                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
665                                 if (data != NULL)
666                                         *data = k->pdata;
667                                 /*
668                                  * Return index where key is stored,
669                                  * substracting the first dummy index
670                                  */
671                                 return (bkt->key_idx[i] - 1);
672                         }
673                 }
674         }
675
676         return -ENOENT;
677 }
678
679 int32_t
680 rte_hash_lookup_with_hash(const struct rte_hash *h,
681                         const void *key, hash_sig_t sig)
682 {
683         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
684         return __rte_hash_lookup_with_hash(h, key, sig, NULL);
685 }
686
687 int32_t
688 rte_hash_lookup(const struct rte_hash *h, const void *key)
689 {
690         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
691         return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key), NULL);
692 }
693
694 int
695 rte_hash_lookup_with_hash_data(const struct rte_hash *h,
696                         const void *key, hash_sig_t sig, void **data)
697 {
698         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
699         return __rte_hash_lookup_with_hash(h, key, sig, data);
700 }
701
702 int
703 rte_hash_lookup_data(const struct rte_hash *h, const void *key, void **data)
704 {
705         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
706         return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key), data);
707 }
708
709 static inline int32_t
710 __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,
711                                                 hash_sig_t sig)
712 {
713         uint32_t bucket_idx;
714         hash_sig_t alt_hash;
715         unsigned i;
716         struct rte_hash_bucket *bkt;
717         struct rte_hash_key *k, *keys = h->key_store;
718
719         bucket_idx = sig & h->bucket_bitmask;
720         bkt = &h->buckets[bucket_idx];
721
722         /* Check if key is in primary location */
723         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
724                 if (bkt->signatures[i].current == sig &&
725                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
726                         k = (struct rte_hash_key *) ((char *)keys +
727                                         bkt->key_idx[i] * h->key_entry_size);
728                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
729                                 bkt->signatures[i].sig = NULL_SIGNATURE;
730                                 rte_ring_sp_enqueue(h->free_slots,
731                                                 (void *)((uintptr_t)bkt->key_idx[i]));
732                                 /*
733                                  * Return index where key is stored,
734                                  * substracting the first dummy index
735                                  */
736                                 return (bkt->key_idx[i] - 1);
737                         }
738                 }
739         }
740
741         /* Calculate secondary hash */
742         alt_hash = rte_hash_secondary_hash(sig);
743         bucket_idx = alt_hash & h->bucket_bitmask;
744         bkt = &h->buckets[bucket_idx];
745
746         /* Check if key is in secondary location */
747         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
748                 if (bkt->signatures[i].current == alt_hash &&
749                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
750                         k = (struct rte_hash_key *) ((char *)keys +
751                                         bkt->key_idx[i] * h->key_entry_size);
752                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
753                                 bkt->signatures[i].sig = NULL_SIGNATURE;
754                                 rte_ring_sp_enqueue(h->free_slots,
755                                                 (void *)((uintptr_t)bkt->key_idx[i]));
756                                 /*
757                                  * Return index where key is stored,
758                                  * substracting the first dummy index
759                                  */
760                                 return (bkt->key_idx[i] - 1);
761                         }
762                 }
763         }
764
765         return -ENOENT;
766 }
767
768 int32_t
769 rte_hash_del_key_with_hash(const struct rte_hash *h,
770                         const void *key, hash_sig_t sig)
771 {
772         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
773         return __rte_hash_del_key_with_hash(h, key, sig);
774 }
775
776 int32_t
777 rte_hash_del_key(const struct rte_hash *h, const void *key)
778 {
779         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
780         return __rte_hash_del_key_with_hash(h, key, rte_hash_hash(h, key));
781 }
782
783 /* Lookup bulk stage 0: Prefetch input key */
784 static inline void
785 lookup_stage0(unsigned *idx, uint64_t *lookup_mask,
786                 const void * const *keys)
787 {
788         *idx = __builtin_ctzl(*lookup_mask);
789         if (*lookup_mask == 0)
790                 *idx = 0;
791
792         rte_prefetch0(keys[*idx]);
793         *lookup_mask &= ~(1llu << *idx);
794 }
795
796 /*
797  * Lookup bulk stage 1: Calculate primary/secondary hashes
798  * and prefetch primary/secondary buckets
799  */
800 static inline void
801 lookup_stage1(unsigned idx, hash_sig_t *prim_hash, hash_sig_t *sec_hash,
802                 const struct rte_hash_bucket **primary_bkt,
803                 const struct rte_hash_bucket **secondary_bkt,
804                 hash_sig_t *hash_vals, const void * const *keys,
805                 const struct rte_hash *h)
806 {
807         *prim_hash = rte_hash_hash(h, keys[idx]);
808         hash_vals[idx] = *prim_hash;
809         *sec_hash = rte_hash_secondary_hash(*prim_hash);
810
811         *primary_bkt = &h->buckets[*prim_hash & h->bucket_bitmask];
812         *secondary_bkt = &h->buckets[*sec_hash & h->bucket_bitmask];
813
814         rte_prefetch0(*primary_bkt);
815         rte_prefetch0(*secondary_bkt);
816 }
817
818 /*
819  * Lookup bulk stage 2:  Search for match hashes in primary/secondary locations
820  * and prefetch first key slot
821  */
822 static inline void
823 lookup_stage2(unsigned idx, hash_sig_t prim_hash, hash_sig_t sec_hash,
824                 const struct rte_hash_bucket *prim_bkt,
825                 const struct rte_hash_bucket *sec_bkt,
826                 const struct rte_hash_key **key_slot, int32_t *positions,
827                 uint64_t *extra_hits_mask, const void *keys,
828                 const struct rte_hash *h)
829 {
830         unsigned prim_hash_matches, sec_hash_matches, key_idx, i;
831         unsigned total_hash_matches;
832
833         prim_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
834         sec_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
835         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
836                 prim_hash_matches |= ((prim_hash == prim_bkt->signatures[i].current) << i);
837                 sec_hash_matches |= ((sec_hash == sec_bkt->signatures[i].current) << i);
838         }
839
840         key_idx = prim_bkt->key_idx[__builtin_ctzl(prim_hash_matches)];
841         if (key_idx == 0)
842                 key_idx = sec_bkt->key_idx[__builtin_ctzl(sec_hash_matches)];
843
844         total_hash_matches = (prim_hash_matches |
845                                 (sec_hash_matches << (RTE_HASH_BUCKET_ENTRIES + 1)));
846         *key_slot = (const struct rte_hash_key *) ((const char *)keys +
847                                         key_idx * h->key_entry_size);
848
849         rte_prefetch0(*key_slot);
850         /*
851          * Return index where key is stored,
852          * substracting the first dummy index
853          */
854         positions[idx] = (key_idx - 1);
855
856         *extra_hits_mask |= (uint64_t)(__builtin_popcount(total_hash_matches) > 3) << idx;
857
858 }
859
860
861 /* Lookup bulk stage 3: Check if key matches, update hit mask and return data */
862 static inline void
863 lookup_stage3(unsigned idx, const struct rte_hash_key *key_slot, const void * const *keys,
864                 void *data[], uint64_t *hits, const struct rte_hash *h)
865 {
866         unsigned hit;
867
868         hit = !h->rte_hash_cmp_eq(key_slot->key, keys[idx], h->key_len);
869         if (data != NULL)
870                 data[idx] = key_slot->pdata;
871
872         *hits |= (uint64_t)(hit) << idx;
873 }
874
875 static inline void
876 __rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
877                         uint32_t num_keys, int32_t *positions,
878                         uint64_t *hit_mask, void *data[])
879 {
880         uint64_t hits = 0;
881         uint64_t extra_hits_mask = 0;
882         uint64_t lookup_mask, miss_mask;
883         unsigned idx;
884         const void *key_store = h->key_store;
885         int ret;
886         hash_sig_t hash_vals[RTE_HASH_LOOKUP_BULK_MAX];
887
888         unsigned idx00, idx01, idx10, idx11, idx20, idx21, idx30, idx31;
889         const struct rte_hash_bucket *primary_bkt10, *primary_bkt11;
890         const struct rte_hash_bucket *secondary_bkt10, *secondary_bkt11;
891         const struct rte_hash_bucket *primary_bkt20, *primary_bkt21;
892         const struct rte_hash_bucket *secondary_bkt20, *secondary_bkt21;
893         const struct rte_hash_key *k_slot20, *k_slot21, *k_slot30, *k_slot31;
894         hash_sig_t primary_hash10, primary_hash11;
895         hash_sig_t secondary_hash10, secondary_hash11;
896         hash_sig_t primary_hash20, primary_hash21;
897         hash_sig_t secondary_hash20, secondary_hash21;
898
899         lookup_mask = (uint64_t) -1 >> (64 - num_keys);
900         miss_mask = lookup_mask;
901
902         lookup_stage0(&idx00, &lookup_mask, keys);
903         lookup_stage0(&idx01, &lookup_mask, keys);
904
905         idx10 = idx00, idx11 = idx01;
906
907         lookup_stage0(&idx00, &lookup_mask, keys);
908         lookup_stage0(&idx01, &lookup_mask, keys);
909         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
910                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
911         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
912                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
913
914         primary_bkt20 = primary_bkt10;
915         primary_bkt21 = primary_bkt11;
916         secondary_bkt20 = secondary_bkt10;
917         secondary_bkt21 = secondary_bkt11;
918         primary_hash20 = primary_hash10;
919         primary_hash21 = primary_hash11;
920         secondary_hash20 = secondary_hash10;
921         secondary_hash21 = secondary_hash11;
922         idx20 = idx10, idx21 = idx11;
923         idx10 = idx00, idx11 = idx01;
924
925         lookup_stage0(&idx00, &lookup_mask, keys);
926         lookup_stage0(&idx01, &lookup_mask, keys);
927         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
928                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
929         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
930                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
931         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
932                         secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
933                         key_store, h);
934         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
935                         secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
936                         key_store, h);
937
938         while (lookup_mask) {
939                 k_slot30 = k_slot20, k_slot31 = k_slot21;
940                 idx30 = idx20, idx31 = idx21;
941                 primary_bkt20 = primary_bkt10;
942                 primary_bkt21 = primary_bkt11;
943                 secondary_bkt20 = secondary_bkt10;
944                 secondary_bkt21 = secondary_bkt11;
945                 primary_hash20 = primary_hash10;
946                 primary_hash21 = primary_hash11;
947                 secondary_hash20 = secondary_hash10;
948                 secondary_hash21 = secondary_hash11;
949                 idx20 = idx10, idx21 = idx11;
950                 idx10 = idx00, idx11 = idx01;
951
952                 lookup_stage0(&idx00, &lookup_mask, keys);
953                 lookup_stage0(&idx01, &lookup_mask, keys);
954                 lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
955                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
956                 lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
957                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
958                 lookup_stage2(idx20, primary_hash20, secondary_hash20,
959                         primary_bkt20, secondary_bkt20, &k_slot20, positions,
960                         &extra_hits_mask, key_store, h);
961                 lookup_stage2(idx21, primary_hash21, secondary_hash21,
962                         primary_bkt21, secondary_bkt21, &k_slot21, positions,
963                         &extra_hits_mask, key_store, h);
964                 lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
965                 lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
966         }
967
968         k_slot30 = k_slot20, k_slot31 = k_slot21;
969         idx30 = idx20, idx31 = idx21;
970         primary_bkt20 = primary_bkt10;
971         primary_bkt21 = primary_bkt11;
972         secondary_bkt20 = secondary_bkt10;
973         secondary_bkt21 = secondary_bkt11;
974         primary_hash20 = primary_hash10;
975         primary_hash21 = primary_hash11;
976         secondary_hash20 = secondary_hash10;
977         secondary_hash21 = secondary_hash11;
978         idx20 = idx10, idx21 = idx11;
979         idx10 = idx00, idx11 = idx01;
980
981         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
982                 &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
983         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
984                 &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
985         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
986                 secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
987                 key_store, h);
988         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
989                 secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
990                 key_store, h);
991         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
992         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
993
994         k_slot30 = k_slot20, k_slot31 = k_slot21;
995         idx30 = idx20, idx31 = idx21;
996         primary_bkt20 = primary_bkt10;
997         primary_bkt21 = primary_bkt11;
998         secondary_bkt20 = secondary_bkt10;
999         secondary_bkt21 = secondary_bkt11;
1000         primary_hash20 = primary_hash10;
1001         primary_hash21 = primary_hash11;
1002         secondary_hash20 = secondary_hash10;
1003         secondary_hash21 = secondary_hash11;
1004         idx20 = idx10, idx21 = idx11;
1005
1006         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
1007                 secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
1008                 key_store, h);
1009         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
1010                 secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
1011                 key_store, h);
1012         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1013         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1014
1015         k_slot30 = k_slot20, k_slot31 = k_slot21;
1016         idx30 = idx20, idx31 = idx21;
1017
1018         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1019         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1020
1021         /* ignore any items we have already found */
1022         extra_hits_mask &= ~hits;
1023
1024         if (unlikely(extra_hits_mask)) {
1025                 /* run a single search for each remaining item */
1026                 do {
1027                         idx = __builtin_ctzl(extra_hits_mask);
1028                         if (data != NULL) {
1029                                 ret = rte_hash_lookup_with_hash_data(h,
1030                                                 keys[idx], hash_vals[idx], &data[idx]);
1031                                 if (ret >= 0)
1032                                         hits |= 1ULL << idx;
1033                         } else {
1034                                 positions[idx] = rte_hash_lookup_with_hash(h,
1035                                                         keys[idx], hash_vals[idx]);
1036                                 if (positions[idx] >= 0)
1037                                         hits |= 1llu << idx;
1038                         }
1039                         extra_hits_mask &= ~(1llu << idx);
1040                 } while (extra_hits_mask);
1041         }
1042
1043         miss_mask &= ~hits;
1044         if (unlikely(miss_mask)) {
1045                 do {
1046                         idx = __builtin_ctzl(miss_mask);
1047                         positions[idx] = -ENOENT;
1048                         miss_mask &= ~(1llu << idx);
1049                 } while (miss_mask);
1050         }
1051
1052         if (hit_mask != NULL)
1053                 *hit_mask = hits;
1054 }
1055
1056 int
1057 rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
1058                       uint32_t num_keys, int32_t *positions)
1059 {
1060         RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) ||
1061                         (num_keys > RTE_HASH_LOOKUP_BULK_MAX) ||
1062                         (positions == NULL)), -EINVAL);
1063
1064         __rte_hash_lookup_bulk(h, keys, num_keys, positions, NULL, NULL);
1065         return 0;
1066 }
1067
1068 int
1069 rte_hash_lookup_bulk_data(const struct rte_hash *h, const void **keys,
1070                       uint32_t num_keys, uint64_t *hit_mask, void *data[])
1071 {
1072         RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) ||
1073                         (num_keys > RTE_HASH_LOOKUP_BULK_MAX) ||
1074                         (hit_mask == NULL)), -EINVAL);
1075
1076         int32_t positions[num_keys];
1077
1078         __rte_hash_lookup_bulk(h, keys, num_keys, positions, hit_mask, data);
1079
1080         /* Return number of hits */
1081         return __builtin_popcountl(*hit_mask);
1082 }
1083
1084 int32_t
1085 rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32_t *next)
1086 {
1087         uint32_t bucket_idx, idx, position;
1088         struct rte_hash_key *next_key;
1089
1090         RETURN_IF_TRUE(((h == NULL) || (next == NULL)), -EINVAL);
1091
1092         const uint32_t total_entries = h->num_buckets * RTE_HASH_BUCKET_ENTRIES;
1093         /* Out of bounds */
1094         if (*next >= total_entries)
1095                 return -ENOENT;
1096
1097         /* Calculate bucket and index of current iterator */
1098         bucket_idx = *next / RTE_HASH_BUCKET_ENTRIES;
1099         idx = *next % RTE_HASH_BUCKET_ENTRIES;
1100
1101         /* If current position is empty, go to the next one */
1102         while (h->buckets[bucket_idx].signatures[idx].sig == NULL_SIGNATURE) {
1103                 (*next)++;
1104                 /* End of table */
1105                 if (*next == total_entries)
1106                         return -ENOENT;
1107                 bucket_idx = *next / RTE_HASH_BUCKET_ENTRIES;
1108                 idx = *next % RTE_HASH_BUCKET_ENTRIES;
1109         }
1110
1111         /* Get position of entry in key table */
1112         position = h->buckets[bucket_idx].key_idx[idx];
1113         next_key = (struct rte_hash_key *) ((char *)h->key_store +
1114                                 position * h->key_entry_size);
1115         /* Return key and data */
1116         *key = next_key->key;
1117         *data = next_key->pdata;
1118
1119         /* Increment iterator */
1120         (*next)++;
1121
1122         return (position - 1);
1123 }