hash: fix scaling by reducing contention
[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 #define LCORE_CACHE_SIZE                8
100
101 typedef int (*rte_hash_cmp_eq_t)(const void *key1, const void *key2, size_t key_len);
102
103 struct lcore_cache {
104         unsigned len; /**< Cache len */
105         void *objs[LCORE_CACHE_SIZE]; /**< Cache objects */
106 } __rte_cache_aligned;
107
108 /** A hash table structure. */
109 struct rte_hash {
110         char name[RTE_HASH_NAMESIZE];   /**< Name of the hash. */
111         uint32_t entries;               /**< Total table entries. */
112         uint32_t num_buckets;           /**< Number of buckets in table. */
113         uint32_t key_len;               /**< Length of hash key. */
114         rte_hash_function hash_func;    /**< Function used to calculate hash. */
115         uint32_t hash_func_init_val;    /**< Init value used by hash_func. */
116         rte_hash_cmp_eq_t rte_hash_cmp_eq; /**< Function used to compare keys. */
117         uint32_t bucket_bitmask;        /**< Bitmask for getting bucket index
118                                                 from hash signature. */
119         uint32_t key_entry_size;         /**< Size of each key entry. */
120
121         struct rte_ring *free_slots;    /**< Ring that stores all indexes
122                                                 of the free slots in the key table */
123         void *key_store;                /**< Table storing all keys and data */
124         struct rte_hash_bucket *buckets;        /**< Table with buckets storing all the
125                                                         hash values and key indexes
126                                                         to the key table*/
127         uint8_t hw_trans_mem_support;   /**< Hardware transactional
128                                                         memory support */
129         struct lcore_cache *local_free_slots;
130         /**< Local cache per lcore, storing some indexes of the free slots */
131 } __rte_cache_aligned;
132
133 /* Structure storing both primary and secondary hashes */
134 struct rte_hash_signatures {
135         union {
136                 struct {
137                         hash_sig_t current;
138                         hash_sig_t alt;
139                 };
140                 uint64_t sig;
141         };
142 };
143
144 /* Structure that stores key-value pair */
145 struct rte_hash_key {
146         union {
147                 uintptr_t idata;
148                 void *pdata;
149         };
150         /* Variable key size */
151         char key[0];
152 } __attribute__((aligned(KEY_ALIGNMENT)));
153
154 /** Bucket structure */
155 struct rte_hash_bucket {
156         struct rte_hash_signatures signatures[RTE_HASH_BUCKET_ENTRIES];
157         /* Includes dummy key index that always contains index 0 */
158         uint32_t key_idx[RTE_HASH_BUCKET_ENTRIES + 1];
159         uint8_t flag[RTE_HASH_BUCKET_ENTRIES];
160 } __rte_cache_aligned;
161
162 struct rte_hash *
163 rte_hash_find_existing(const char *name)
164 {
165         struct rte_hash *h = NULL;
166         struct rte_tailq_entry *te;
167         struct rte_hash_list *hash_list;
168
169         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
170
171         rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
172         TAILQ_FOREACH(te, hash_list, next) {
173                 h = (struct rte_hash *) te->data;
174                 if (strncmp(name, h->name, RTE_HASH_NAMESIZE) == 0)
175                         break;
176         }
177         rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
178
179         if (te == NULL) {
180                 rte_errno = ENOENT;
181                 return NULL;
182         }
183         return h;
184 }
185
186 struct rte_hash *
187 rte_hash_create(const struct rte_hash_parameters *params)
188 {
189         struct rte_hash *h = NULL;
190         struct rte_tailq_entry *te = NULL;
191         struct rte_hash_list *hash_list;
192         struct rte_ring *r = NULL;
193         char hash_name[RTE_HASH_NAMESIZE];
194         void *k = NULL;
195         void *buckets = NULL;
196         char ring_name[RTE_RING_NAMESIZE];
197         unsigned num_key_slots;
198         unsigned hw_trans_mem_support = 0;
199         unsigned i;
200
201         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
202
203         if (params == NULL) {
204                 RTE_LOG(ERR, HASH, "rte_hash_create has no parameters\n");
205                 return NULL;
206         }
207
208         /* Check for valid parameters */
209         if ((params->entries > RTE_HASH_ENTRIES_MAX) ||
210                         (params->entries < RTE_HASH_BUCKET_ENTRIES) ||
211                         !rte_is_power_of_2(RTE_HASH_BUCKET_ENTRIES) ||
212                         (params->key_len == 0)) {
213                 rte_errno = EINVAL;
214                 RTE_LOG(ERR, HASH, "rte_hash_create has invalid parameters\n");
215                 return NULL;
216         }
217
218         /* Check extra flags field to check extra options. */
219         if (params->extra_flag & RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT)
220                 hw_trans_mem_support = 1;
221
222         snprintf(hash_name, sizeof(hash_name), "HT_%s", params->name);
223
224         /* Guarantee there's no existing */
225         h = rte_hash_find_existing(params->name);
226         if (h != NULL)
227                 return h;
228
229         te = rte_zmalloc("HASH_TAILQ_ENTRY", sizeof(*te), 0);
230         if (te == NULL) {
231                 RTE_LOG(ERR, HASH, "tailq entry allocation failed\n");
232                 goto err;
233         }
234
235         h = (struct rte_hash *)rte_zmalloc_socket(hash_name, sizeof(struct rte_hash),
236                                         RTE_CACHE_LINE_SIZE, params->socket_id);
237
238         if (h == NULL) {
239                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
240                 goto err;
241         }
242
243         const uint32_t num_buckets = rte_align32pow2(params->entries)
244                                         / RTE_HASH_BUCKET_ENTRIES;
245
246         buckets = rte_zmalloc_socket(NULL,
247                                 num_buckets * sizeof(struct rte_hash_bucket),
248                                 RTE_CACHE_LINE_SIZE, params->socket_id);
249
250         if (buckets == NULL) {
251                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
252                 goto err;
253         }
254
255         const uint32_t key_entry_size = sizeof(struct rte_hash_key) + params->key_len;
256
257         /* Store all keys and leave the first entry as a dummy entry for lookup_bulk */
258         if (hw_trans_mem_support)
259                 /*
260                  * Increase number of slots by total number of indices
261                  * that can be stored in the lcore caches
262                  * except for the first cache
263                  */
264                 num_key_slots = params->entries + (RTE_MAX_LCORE - 1) *
265                                         LCORE_CACHE_SIZE + 1;
266         else
267                 num_key_slots = params->entries + 1;
268
269         const uint64_t key_tbl_size = (uint64_t) key_entry_size * num_key_slots;
270
271         k = rte_zmalloc_socket(NULL, key_tbl_size,
272                         RTE_CACHE_LINE_SIZE, params->socket_id);
273
274         if (k == NULL) {
275                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
276                 goto err;
277         }
278
279 /*
280  * If x86 architecture is used, select appropriate compare function,
281  * which may use x86 instrinsics, otherwise use memcmp
282  */
283 #if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) || defined(RTE_ARCH_X86_X32)
284         /* Select function to compare keys */
285         switch (params->key_len) {
286         case 16:
287                 h->rte_hash_cmp_eq = rte_hash_k16_cmp_eq;
288                 break;
289         case 32:
290                 h->rte_hash_cmp_eq = rte_hash_k32_cmp_eq;
291                 break;
292         case 48:
293                 h->rte_hash_cmp_eq = rte_hash_k48_cmp_eq;
294                 break;
295         case 64:
296                 h->rte_hash_cmp_eq = rte_hash_k64_cmp_eq;
297                 break;
298         case 80:
299                 h->rte_hash_cmp_eq = rte_hash_k80_cmp_eq;
300                 break;
301         case 96:
302                 h->rte_hash_cmp_eq = rte_hash_k96_cmp_eq;
303                 break;
304         case 112:
305                 h->rte_hash_cmp_eq = rte_hash_k112_cmp_eq;
306                 break;
307         case 128:
308                 h->rte_hash_cmp_eq = rte_hash_k128_cmp_eq;
309                 break;
310         default:
311                 /* If key is not multiple of 16, use generic memcmp */
312                 h->rte_hash_cmp_eq = memcmp;
313         }
314 #else
315         h->rte_hash_cmp_eq = memcmp;
316 #endif
317
318         snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name);
319         r = rte_ring_create(ring_name, rte_align32pow2(num_key_slots),
320                         params->socket_id, 0);
321         if (r == NULL) {
322                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
323                 goto err;
324         }
325
326         if (hw_trans_mem_support) {
327                 h->local_free_slots = rte_zmalloc_socket(NULL,
328                                 sizeof(struct lcore_cache) * RTE_MAX_LCORE,
329                                 RTE_CACHE_LINE_SIZE, params->socket_id);
330         }
331
332         /* Setup hash context */
333         snprintf(h->name, sizeof(h->name), "%s", params->name);
334         h->entries = params->entries;
335         h->key_len = params->key_len;
336         h->key_entry_size = key_entry_size;
337         h->hash_func_init_val = params->hash_func_init_val;
338
339         h->num_buckets = num_buckets;
340         h->bucket_bitmask = h->num_buckets - 1;
341         h->buckets = buckets;
342         h->hash_func = (params->hash_func == NULL) ?
343                 DEFAULT_HASH_FUNC : params->hash_func;
344         h->key_store = k;
345         h->free_slots = r;
346         h->hw_trans_mem_support = hw_trans_mem_support;
347
348         /* populate the free slots ring. Entry zero is reserved for key misses */
349         for (i = 1; i < params->entries + 1; i++)
350                 rte_ring_sp_enqueue(r, (void *)((uintptr_t) i));
351
352         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
353         te->data = (void *) h;
354         TAILQ_INSERT_TAIL(hash_list, te, next);
355         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
356
357         return h;
358 err:
359         rte_free(te);
360         rte_free(h);
361         rte_free(buckets);
362         rte_free(k);
363         return NULL;
364 }
365
366 void
367 rte_hash_free(struct rte_hash *h)
368 {
369         struct rte_tailq_entry *te;
370         struct rte_hash_list *hash_list;
371
372         if (h == NULL)
373                 return;
374
375         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
376
377         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
378
379         /* find out tailq entry */
380         TAILQ_FOREACH(te, hash_list, next) {
381                 if (te->data == (void *) h)
382                         break;
383         }
384
385         if (te == NULL) {
386                 rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
387                 return;
388         }
389
390         TAILQ_REMOVE(hash_list, te, next);
391
392         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
393
394         if (h->hw_trans_mem_support)
395                 rte_free(h->local_free_slots);
396
397         rte_ring_free(h->free_slots);
398         rte_free(h->key_store);
399         rte_free(h->buckets);
400         rte_free(h);
401         rte_free(te);
402 }
403
404 hash_sig_t
405 rte_hash_hash(const struct rte_hash *h, const void *key)
406 {
407         /* calc hash result by key */
408         return h->hash_func(key, h->key_len, h->hash_func_init_val);
409 }
410
411 /* Calc the secondary hash value from the primary hash value of a given key */
412 static inline hash_sig_t
413 rte_hash_secondary_hash(const hash_sig_t primary_hash)
414 {
415         static const unsigned all_bits_shift = 12;
416         static const unsigned alt_bits_xor = 0x5bd1e995;
417
418         uint32_t tag = primary_hash >> all_bits_shift;
419
420         return (primary_hash ^ ((tag + 1) * alt_bits_xor));
421 }
422
423 void
424 rte_hash_reset(struct rte_hash *h)
425 {
426         void *ptr;
427         unsigned i;
428
429         if (h == NULL)
430                 return;
431
432         memset(h->buckets, 0, h->num_buckets * sizeof(struct rte_hash_bucket));
433         memset(h->key_store, 0, h->key_entry_size * (h->entries + 1));
434
435         /* clear the free ring */
436         while (rte_ring_dequeue(h->free_slots, &ptr) == 0)
437                 rte_pause();
438
439         /* Repopulate the free slots ring. Entry zero is reserved for key misses */
440         for (i = 1; i < h->entries + 1; i++)
441                 rte_ring_sp_enqueue(h->free_slots, (void *)((uintptr_t) i));
442
443         if (h->hw_trans_mem_support) {
444                 /* Reset local caches per lcore */
445                 for (i = 0; i < RTE_MAX_LCORE; i++)
446                         h->local_free_slots[i].len = 0;
447         }
448 }
449
450 /* Search for an entry that can be pushed to its alternative location */
451 static inline int
452 make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
453 {
454         unsigned i, j;
455         int ret;
456         uint32_t next_bucket_idx;
457         struct rte_hash_bucket *next_bkt[RTE_HASH_BUCKET_ENTRIES];
458
459         /*
460          * Push existing item (search for bucket with space in
461          * alternative locations) to its alternative location
462          */
463         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
464                 /* Search for space in alternative locations */
465                 next_bucket_idx = bkt->signatures[i].alt & h->bucket_bitmask;
466                 next_bkt[i] = &h->buckets[next_bucket_idx];
467                 for (j = 0; j < RTE_HASH_BUCKET_ENTRIES; j++) {
468                         if (next_bkt[i]->signatures[j].sig == NULL_SIGNATURE)
469                                 break;
470                 }
471
472                 if (j != RTE_HASH_BUCKET_ENTRIES)
473                         break;
474         }
475
476         /* Alternative location has spare room (end of recursive function) */
477         if (i != RTE_HASH_BUCKET_ENTRIES) {
478                 next_bkt[i]->signatures[j].alt = bkt->signatures[i].current;
479                 next_bkt[i]->signatures[j].current = bkt->signatures[i].alt;
480                 next_bkt[i]->key_idx[j] = bkt->key_idx[i];
481                 return i;
482         }
483
484         /* Pick entry that has not been pushed yet */
485         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++)
486                 if (bkt->flag[i] == 0)
487                         break;
488
489         /* All entries have been pushed, so entry cannot be added */
490         if (i == RTE_HASH_BUCKET_ENTRIES)
491                 return -ENOSPC;
492
493         /* Set flag to indicate that this entry is going to be pushed */
494         bkt->flag[i] = 1;
495         /* Need room in alternative bucket to insert the pushed entry */
496         ret = make_space_bucket(h, next_bkt[i]);
497         /*
498          * After recursive function.
499          * Clear flags and insert the pushed entry
500          * in its alternative location if successful,
501          * or return error
502          */
503         bkt->flag[i] = 0;
504         if (ret >= 0) {
505                 next_bkt[i]->signatures[ret].alt = bkt->signatures[i].current;
506                 next_bkt[i]->signatures[ret].current = bkt->signatures[i].alt;
507                 next_bkt[i]->key_idx[ret] = bkt->key_idx[i];
508                 return i;
509         } else
510                 return ret;
511
512 }
513
514 /*
515  * Function called to enqueue back an index in the cache/ring,
516  * as slot has not being used and it can be used in the
517  * next addition attempt.
518  */
519 static inline void
520 enqueue_slot_back(const struct rte_hash *h,
521                 struct lcore_cache *cached_free_slots,
522                 void *slot_id)
523 {
524         if (h->hw_trans_mem_support) {
525                 cached_free_slots->objs[cached_free_slots->len] = slot_id;
526                 cached_free_slots->len++;
527         } else
528                 rte_ring_sp_enqueue(h->free_slots, slot_id);
529 }
530
531 static inline int32_t
532 __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,
533                                                 hash_sig_t sig, void *data)
534 {
535         hash_sig_t alt_hash;
536         uint32_t prim_bucket_idx, sec_bucket_idx;
537         unsigned i;
538         struct rte_hash_bucket *prim_bkt, *sec_bkt;
539         struct rte_hash_key *new_k, *k, *keys = h->key_store;
540         void *slot_id = NULL;
541         uint32_t new_idx;
542         int ret;
543         unsigned n_slots;
544         unsigned lcore_id;
545         struct lcore_cache *cached_free_slots = NULL;
546
547         prim_bucket_idx = sig & h->bucket_bitmask;
548         prim_bkt = &h->buckets[prim_bucket_idx];
549         rte_prefetch0(prim_bkt);
550
551         alt_hash = rte_hash_secondary_hash(sig);
552         sec_bucket_idx = alt_hash & h->bucket_bitmask;
553         sec_bkt = &h->buckets[sec_bucket_idx];
554         rte_prefetch0(sec_bkt);
555
556         /* Get a new slot for storing the new key */
557         if (h->hw_trans_mem_support) {
558                 lcore_id = rte_lcore_id();
559                 cached_free_slots = &h->local_free_slots[lcore_id];
560                 /* Try to get a free slot from the local cache */
561                 if (cached_free_slots->len == 0) {
562                         /* Need to get another burst of free slots from global ring */
563                         n_slots = rte_ring_mc_dequeue_burst(h->free_slots,
564                                         cached_free_slots->objs, LCORE_CACHE_SIZE);
565                         if (n_slots == 0)
566                                 return -ENOSPC;
567
568                         cached_free_slots->len += n_slots;
569                 }
570
571                 /* Get a free slot from the local cache */
572                 cached_free_slots->len--;
573                 slot_id = cached_free_slots->objs[cached_free_slots->len];
574         } else {
575                 if (rte_ring_sc_dequeue(h->free_slots, &slot_id) != 0)
576                         return -ENOSPC;
577         }
578
579         new_k = RTE_PTR_ADD(keys, (uintptr_t)slot_id * h->key_entry_size);
580         rte_prefetch0(new_k);
581         new_idx = (uint32_t)((uintptr_t) slot_id);
582
583         /* Check if key is already inserted in primary location */
584         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
585                 if (prim_bkt->signatures[i].current == sig &&
586                                 prim_bkt->signatures[i].alt == alt_hash) {
587                         k = (struct rte_hash_key *) ((char *)keys +
588                                         prim_bkt->key_idx[i] * h->key_entry_size);
589                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
590                                 /* Enqueue index of free slot back in the ring. */
591                                 enqueue_slot_back(h, cached_free_slots, slot_id);
592                                 /* Update data */
593                                 k->pdata = data;
594                                 /*
595                                  * Return index where key is stored,
596                                  * substracting the first dummy index
597                                  */
598                                 return (prim_bkt->key_idx[i] - 1);
599                         }
600                 }
601         }
602
603         /* Check if key is already inserted in secondary location */
604         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
605                 if (sec_bkt->signatures[i].alt == sig &&
606                                 sec_bkt->signatures[i].current == alt_hash) {
607                         k = (struct rte_hash_key *) ((char *)keys +
608                                         sec_bkt->key_idx[i] * h->key_entry_size);
609                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
610                                 /* Enqueue index of free slot back in the ring. */
611                                 enqueue_slot_back(h, cached_free_slots, slot_id);
612                                 /* Update data */
613                                 k->pdata = data;
614                                 /*
615                                  * Return index where key is stored,
616                                  * substracting the first dummy index
617                                  */
618                                 return (sec_bkt->key_idx[i] - 1);
619                         }
620                 }
621         }
622
623         /* Copy key */
624         rte_memcpy(new_k->key, key, h->key_len);
625         new_k->pdata = data;
626
627         /* Insert new entry is there is room in the primary bucket */
628         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
629                 /* Check if slot is available */
630                 if (likely(prim_bkt->signatures[i].sig == NULL_SIGNATURE)) {
631                         prim_bkt->signatures[i].current = sig;
632                         prim_bkt->signatures[i].alt = alt_hash;
633                         prim_bkt->key_idx[i] = new_idx;
634                         return new_idx - 1;
635                 }
636         }
637
638         /* Primary bucket is full, so we need to make space for new entry */
639         ret = make_space_bucket(h, prim_bkt);
640         /*
641          * After recursive function.
642          * Insert the new entry in the position of the pushed entry
643          * if successful or return error and
644          * store the new slot back in the ring
645          */
646         if (ret >= 0) {
647                 prim_bkt->signatures[ret].current = sig;
648                 prim_bkt->signatures[ret].alt = alt_hash;
649                 prim_bkt->key_idx[ret] = new_idx;
650                 return (new_idx - 1);
651         }
652
653         /* Error in addition, store new slot back in the ring and return error */
654         enqueue_slot_back(h, cached_free_slots, (void *)((uintptr_t) new_idx));
655
656         return ret;
657 }
658
659 int32_t
660 rte_hash_add_key_with_hash(const struct rte_hash *h,
661                         const void *key, hash_sig_t sig)
662 {
663         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
664         return __rte_hash_add_key_with_hash(h, key, sig, 0);
665 }
666
667 int32_t
668 rte_hash_add_key(const struct rte_hash *h, const void *key)
669 {
670         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
671         return __rte_hash_add_key_with_hash(h, key, rte_hash_hash(h, key), 0);
672 }
673
674 int
675 rte_hash_add_key_with_hash_data(const struct rte_hash *h,
676                         const void *key, hash_sig_t sig, void *data)
677 {
678         int ret;
679
680         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
681         ret = __rte_hash_add_key_with_hash(h, key, sig, data);
682         if (ret >= 0)
683                 return 0;
684         else
685                 return ret;
686 }
687
688 int
689 rte_hash_add_key_data(const struct rte_hash *h, const void *key, void *data)
690 {
691         int ret;
692
693         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
694
695         ret = __rte_hash_add_key_with_hash(h, key, rte_hash_hash(h, key), data);
696         if (ret >= 0)
697                 return 0;
698         else
699                 return ret;
700 }
701 static inline int32_t
702 __rte_hash_lookup_with_hash(const struct rte_hash *h, const void *key,
703                                         hash_sig_t sig, void **data)
704 {
705         uint32_t bucket_idx;
706         hash_sig_t alt_hash;
707         unsigned i;
708         struct rte_hash_bucket *bkt;
709         struct rte_hash_key *k, *keys = h->key_store;
710
711         bucket_idx = sig & h->bucket_bitmask;
712         bkt = &h->buckets[bucket_idx];
713
714         /* Check if key is in primary location */
715         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
716                 if (bkt->signatures[i].current == sig &&
717                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
718                         k = (struct rte_hash_key *) ((char *)keys +
719                                         bkt->key_idx[i] * h->key_entry_size);
720                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
721                                 if (data != NULL)
722                                         *data = k->pdata;
723                                 /*
724                                  * Return index where key is stored,
725                                  * substracting the first dummy index
726                                  */
727                                 return (bkt->key_idx[i] - 1);
728                         }
729                 }
730         }
731
732         /* Calculate secondary hash */
733         alt_hash = rte_hash_secondary_hash(sig);
734         bucket_idx = alt_hash & h->bucket_bitmask;
735         bkt = &h->buckets[bucket_idx];
736
737         /* Check if key is in secondary location */
738         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
739                 if (bkt->signatures[i].current == alt_hash &&
740                                 bkt->signatures[i].alt == sig) {
741                         k = (struct rte_hash_key *) ((char *)keys +
742                                         bkt->key_idx[i] * h->key_entry_size);
743                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
744                                 if (data != NULL)
745                                         *data = k->pdata;
746                                 /*
747                                  * Return index where key is stored,
748                                  * substracting the first dummy index
749                                  */
750                                 return (bkt->key_idx[i] - 1);
751                         }
752                 }
753         }
754
755         return -ENOENT;
756 }
757
758 int32_t
759 rte_hash_lookup_with_hash(const struct rte_hash *h,
760                         const void *key, hash_sig_t sig)
761 {
762         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
763         return __rte_hash_lookup_with_hash(h, key, sig, NULL);
764 }
765
766 int32_t
767 rte_hash_lookup(const struct rte_hash *h, const void *key)
768 {
769         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
770         return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key), NULL);
771 }
772
773 int
774 rte_hash_lookup_with_hash_data(const struct rte_hash *h,
775                         const void *key, hash_sig_t sig, void **data)
776 {
777         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
778         return __rte_hash_lookup_with_hash(h, key, sig, data);
779 }
780
781 int
782 rte_hash_lookup_data(const struct rte_hash *h, const void *key, void **data)
783 {
784         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
785         return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key), data);
786 }
787
788 static inline void
789 remove_entry(const struct rte_hash *h, struct rte_hash_bucket *bkt, unsigned i)
790 {
791         unsigned lcore_id, n_slots;
792         struct lcore_cache *cached_free_slots;
793
794         bkt->signatures[i].sig = NULL_SIGNATURE;
795         if (h->hw_trans_mem_support) {
796                 lcore_id = rte_lcore_id();
797                 cached_free_slots = &h->local_free_slots[lcore_id];
798                 /* Cache full, need to free it. */
799                 if (cached_free_slots->len == LCORE_CACHE_SIZE) {
800                         /* Need to enqueue the free slots in global ring. */
801                         n_slots = rte_ring_mp_enqueue_burst(h->free_slots,
802                                                 cached_free_slots->objs,
803                                                 LCORE_CACHE_SIZE);
804                         cached_free_slots->len -= n_slots;
805                 }
806                 /* Put index of new free slot in cache. */
807                 cached_free_slots->objs[cached_free_slots->len] =
808                                 (void *)((uintptr_t)bkt->key_idx[i]);
809                 cached_free_slots->len++;
810         } else {
811                 rte_ring_sp_enqueue(h->free_slots,
812                                 (void *)((uintptr_t)bkt->key_idx[i]));
813         }
814 }
815
816 static inline int32_t
817 __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,
818                                                 hash_sig_t sig)
819 {
820         uint32_t bucket_idx;
821         hash_sig_t alt_hash;
822         unsigned i;
823         struct rte_hash_bucket *bkt;
824         struct rte_hash_key *k, *keys = h->key_store;
825
826         bucket_idx = sig & h->bucket_bitmask;
827         bkt = &h->buckets[bucket_idx];
828
829         /* Check if key is in primary location */
830         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
831                 if (bkt->signatures[i].current == sig &&
832                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
833                         k = (struct rte_hash_key *) ((char *)keys +
834                                         bkt->key_idx[i] * h->key_entry_size);
835                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
836                                 remove_entry(h, bkt, i);
837
838                                 /*
839                                  * Return index where key is stored,
840                                  * substracting the first dummy index
841                                  */
842                                 return (bkt->key_idx[i] - 1);
843                         }
844                 }
845         }
846
847         /* Calculate secondary hash */
848         alt_hash = rte_hash_secondary_hash(sig);
849         bucket_idx = alt_hash & h->bucket_bitmask;
850         bkt = &h->buckets[bucket_idx];
851
852         /* Check if key is in secondary location */
853         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
854                 if (bkt->signatures[i].current == alt_hash &&
855                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
856                         k = (struct rte_hash_key *) ((char *)keys +
857                                         bkt->key_idx[i] * h->key_entry_size);
858                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
859                                 remove_entry(h, bkt, i);
860
861                                 /*
862                                  * Return index where key is stored,
863                                  * substracting the first dummy index
864                                  */
865                                 return (bkt->key_idx[i] - 1);
866                         }
867                 }
868         }
869
870         return -ENOENT;
871 }
872
873 int32_t
874 rte_hash_del_key_with_hash(const struct rte_hash *h,
875                         const void *key, hash_sig_t sig)
876 {
877         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
878         return __rte_hash_del_key_with_hash(h, key, sig);
879 }
880
881 int32_t
882 rte_hash_del_key(const struct rte_hash *h, const void *key)
883 {
884         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
885         return __rte_hash_del_key_with_hash(h, key, rte_hash_hash(h, key));
886 }
887
888 /* Lookup bulk stage 0: Prefetch input key */
889 static inline void
890 lookup_stage0(unsigned *idx, uint64_t *lookup_mask,
891                 const void * const *keys)
892 {
893         *idx = __builtin_ctzl(*lookup_mask);
894         if (*lookup_mask == 0)
895                 *idx = 0;
896
897         rte_prefetch0(keys[*idx]);
898         *lookup_mask &= ~(1llu << *idx);
899 }
900
901 /*
902  * Lookup bulk stage 1: Calculate primary/secondary hashes
903  * and prefetch primary/secondary buckets
904  */
905 static inline void
906 lookup_stage1(unsigned idx, hash_sig_t *prim_hash, hash_sig_t *sec_hash,
907                 const struct rte_hash_bucket **primary_bkt,
908                 const struct rte_hash_bucket **secondary_bkt,
909                 hash_sig_t *hash_vals, const void * const *keys,
910                 const struct rte_hash *h)
911 {
912         *prim_hash = rte_hash_hash(h, keys[idx]);
913         hash_vals[idx] = *prim_hash;
914         *sec_hash = rte_hash_secondary_hash(*prim_hash);
915
916         *primary_bkt = &h->buckets[*prim_hash & h->bucket_bitmask];
917         *secondary_bkt = &h->buckets[*sec_hash & h->bucket_bitmask];
918
919         rte_prefetch0(*primary_bkt);
920         rte_prefetch0(*secondary_bkt);
921 }
922
923 /*
924  * Lookup bulk stage 2:  Search for match hashes in primary/secondary locations
925  * and prefetch first key slot
926  */
927 static inline void
928 lookup_stage2(unsigned idx, hash_sig_t prim_hash, hash_sig_t sec_hash,
929                 const struct rte_hash_bucket *prim_bkt,
930                 const struct rte_hash_bucket *sec_bkt,
931                 const struct rte_hash_key **key_slot, int32_t *positions,
932                 uint64_t *extra_hits_mask, const void *keys,
933                 const struct rte_hash *h)
934 {
935         unsigned prim_hash_matches, sec_hash_matches, key_idx, i;
936         unsigned total_hash_matches;
937
938         prim_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
939         sec_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
940         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
941                 prim_hash_matches |= ((prim_hash == prim_bkt->signatures[i].current) << i);
942                 sec_hash_matches |= ((sec_hash == sec_bkt->signatures[i].current) << i);
943         }
944
945         key_idx = prim_bkt->key_idx[__builtin_ctzl(prim_hash_matches)];
946         if (key_idx == 0)
947                 key_idx = sec_bkt->key_idx[__builtin_ctzl(sec_hash_matches)];
948
949         total_hash_matches = (prim_hash_matches |
950                                 (sec_hash_matches << (RTE_HASH_BUCKET_ENTRIES + 1)));
951         *key_slot = (const struct rte_hash_key *) ((const char *)keys +
952                                         key_idx * h->key_entry_size);
953
954         rte_prefetch0(*key_slot);
955         /*
956          * Return index where key is stored,
957          * substracting the first dummy index
958          */
959         positions[idx] = (key_idx - 1);
960
961         *extra_hits_mask |= (uint64_t)(__builtin_popcount(total_hash_matches) > 3) << idx;
962
963 }
964
965
966 /* Lookup bulk stage 3: Check if key matches, update hit mask and return data */
967 static inline void
968 lookup_stage3(unsigned idx, const struct rte_hash_key *key_slot, const void * const *keys,
969                 void *data[], uint64_t *hits, const struct rte_hash *h)
970 {
971         unsigned hit;
972
973         hit = !h->rte_hash_cmp_eq(key_slot->key, keys[idx], h->key_len);
974         if (data != NULL)
975                 data[idx] = key_slot->pdata;
976
977         *hits |= (uint64_t)(hit) << idx;
978 }
979
980 static inline void
981 __rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
982                         uint32_t num_keys, int32_t *positions,
983                         uint64_t *hit_mask, void *data[])
984 {
985         uint64_t hits = 0;
986         uint64_t extra_hits_mask = 0;
987         uint64_t lookup_mask, miss_mask;
988         unsigned idx;
989         const void *key_store = h->key_store;
990         int ret;
991         hash_sig_t hash_vals[RTE_HASH_LOOKUP_BULK_MAX];
992
993         unsigned idx00, idx01, idx10, idx11, idx20, idx21, idx30, idx31;
994         const struct rte_hash_bucket *primary_bkt10, *primary_bkt11;
995         const struct rte_hash_bucket *secondary_bkt10, *secondary_bkt11;
996         const struct rte_hash_bucket *primary_bkt20, *primary_bkt21;
997         const struct rte_hash_bucket *secondary_bkt20, *secondary_bkt21;
998         const struct rte_hash_key *k_slot20, *k_slot21, *k_slot30, *k_slot31;
999         hash_sig_t primary_hash10, primary_hash11;
1000         hash_sig_t secondary_hash10, secondary_hash11;
1001         hash_sig_t primary_hash20, primary_hash21;
1002         hash_sig_t secondary_hash20, secondary_hash21;
1003
1004         lookup_mask = (uint64_t) -1 >> (64 - num_keys);
1005         miss_mask = lookup_mask;
1006
1007         lookup_stage0(&idx00, &lookup_mask, keys);
1008         lookup_stage0(&idx01, &lookup_mask, keys);
1009
1010         idx10 = idx00, idx11 = idx01;
1011
1012         lookup_stage0(&idx00, &lookup_mask, keys);
1013         lookup_stage0(&idx01, &lookup_mask, keys);
1014         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
1015                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
1016         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
1017                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
1018
1019         primary_bkt20 = primary_bkt10;
1020         primary_bkt21 = primary_bkt11;
1021         secondary_bkt20 = secondary_bkt10;
1022         secondary_bkt21 = secondary_bkt11;
1023         primary_hash20 = primary_hash10;
1024         primary_hash21 = primary_hash11;
1025         secondary_hash20 = secondary_hash10;
1026         secondary_hash21 = secondary_hash11;
1027         idx20 = idx10, idx21 = idx11;
1028         idx10 = idx00, idx11 = idx01;
1029
1030         lookup_stage0(&idx00, &lookup_mask, keys);
1031         lookup_stage0(&idx01, &lookup_mask, keys);
1032         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
1033                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
1034         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
1035                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
1036         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
1037                         secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
1038                         key_store, h);
1039         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
1040                         secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
1041                         key_store, h);
1042
1043         while (lookup_mask) {
1044                 k_slot30 = k_slot20, k_slot31 = k_slot21;
1045                 idx30 = idx20, idx31 = idx21;
1046                 primary_bkt20 = primary_bkt10;
1047                 primary_bkt21 = primary_bkt11;
1048                 secondary_bkt20 = secondary_bkt10;
1049                 secondary_bkt21 = secondary_bkt11;
1050                 primary_hash20 = primary_hash10;
1051                 primary_hash21 = primary_hash11;
1052                 secondary_hash20 = secondary_hash10;
1053                 secondary_hash21 = secondary_hash11;
1054                 idx20 = idx10, idx21 = idx11;
1055                 idx10 = idx00, idx11 = idx01;
1056
1057                 lookup_stage0(&idx00, &lookup_mask, keys);
1058                 lookup_stage0(&idx01, &lookup_mask, keys);
1059                 lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
1060                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
1061                 lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
1062                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
1063                 lookup_stage2(idx20, primary_hash20, secondary_hash20,
1064                         primary_bkt20, secondary_bkt20, &k_slot20, positions,
1065                         &extra_hits_mask, key_store, h);
1066                 lookup_stage2(idx21, primary_hash21, secondary_hash21,
1067                         primary_bkt21, secondary_bkt21, &k_slot21, positions,
1068                         &extra_hits_mask, key_store, h);
1069                 lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1070                 lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1071         }
1072
1073         k_slot30 = k_slot20, k_slot31 = k_slot21;
1074         idx30 = idx20, idx31 = idx21;
1075         primary_bkt20 = primary_bkt10;
1076         primary_bkt21 = primary_bkt11;
1077         secondary_bkt20 = secondary_bkt10;
1078         secondary_bkt21 = secondary_bkt11;
1079         primary_hash20 = primary_hash10;
1080         primary_hash21 = primary_hash11;
1081         secondary_hash20 = secondary_hash10;
1082         secondary_hash21 = secondary_hash11;
1083         idx20 = idx10, idx21 = idx11;
1084         idx10 = idx00, idx11 = idx01;
1085
1086         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
1087                 &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
1088         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
1089                 &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
1090         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
1091                 secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
1092                 key_store, h);
1093         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
1094                 secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
1095                 key_store, h);
1096         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1097         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1098
1099         k_slot30 = k_slot20, k_slot31 = k_slot21;
1100         idx30 = idx20, idx31 = idx21;
1101         primary_bkt20 = primary_bkt10;
1102         primary_bkt21 = primary_bkt11;
1103         secondary_bkt20 = secondary_bkt10;
1104         secondary_bkt21 = secondary_bkt11;
1105         primary_hash20 = primary_hash10;
1106         primary_hash21 = primary_hash11;
1107         secondary_hash20 = secondary_hash10;
1108         secondary_hash21 = secondary_hash11;
1109         idx20 = idx10, idx21 = idx11;
1110
1111         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
1112                 secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
1113                 key_store, h);
1114         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
1115                 secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
1116                 key_store, h);
1117         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1118         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1119
1120         k_slot30 = k_slot20, k_slot31 = k_slot21;
1121         idx30 = idx20, idx31 = idx21;
1122
1123         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1124         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1125
1126         /* ignore any items we have already found */
1127         extra_hits_mask &= ~hits;
1128
1129         if (unlikely(extra_hits_mask)) {
1130                 /* run a single search for each remaining item */
1131                 do {
1132                         idx = __builtin_ctzl(extra_hits_mask);
1133                         if (data != NULL) {
1134                                 ret = rte_hash_lookup_with_hash_data(h,
1135                                                 keys[idx], hash_vals[idx], &data[idx]);
1136                                 if (ret >= 0)
1137                                         hits |= 1ULL << idx;
1138                         } else {
1139                                 positions[idx] = rte_hash_lookup_with_hash(h,
1140                                                         keys[idx], hash_vals[idx]);
1141                                 if (positions[idx] >= 0)
1142                                         hits |= 1llu << idx;
1143                         }
1144                         extra_hits_mask &= ~(1llu << idx);
1145                 } while (extra_hits_mask);
1146         }
1147
1148         miss_mask &= ~hits;
1149         if (unlikely(miss_mask)) {
1150                 do {
1151                         idx = __builtin_ctzl(miss_mask);
1152                         positions[idx] = -ENOENT;
1153                         miss_mask &= ~(1llu << idx);
1154                 } while (miss_mask);
1155         }
1156
1157         if (hit_mask != NULL)
1158                 *hit_mask = hits;
1159 }
1160
1161 int
1162 rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
1163                       uint32_t num_keys, int32_t *positions)
1164 {
1165         RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) ||
1166                         (num_keys > RTE_HASH_LOOKUP_BULK_MAX) ||
1167                         (positions == NULL)), -EINVAL);
1168
1169         __rte_hash_lookup_bulk(h, keys, num_keys, positions, NULL, NULL);
1170         return 0;
1171 }
1172
1173 int
1174 rte_hash_lookup_bulk_data(const struct rte_hash *h, const void **keys,
1175                       uint32_t num_keys, uint64_t *hit_mask, void *data[])
1176 {
1177         RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) ||
1178                         (num_keys > RTE_HASH_LOOKUP_BULK_MAX) ||
1179                         (hit_mask == NULL)), -EINVAL);
1180
1181         int32_t positions[num_keys];
1182
1183         __rte_hash_lookup_bulk(h, keys, num_keys, positions, hit_mask, data);
1184
1185         /* Return number of hits */
1186         return __builtin_popcountl(*hit_mask);
1187 }
1188
1189 int32_t
1190 rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32_t *next)
1191 {
1192         uint32_t bucket_idx, idx, position;
1193         struct rte_hash_key *next_key;
1194
1195         RETURN_IF_TRUE(((h == NULL) || (next == NULL)), -EINVAL);
1196
1197         const uint32_t total_entries = h->num_buckets * RTE_HASH_BUCKET_ENTRIES;
1198         /* Out of bounds */
1199         if (*next >= total_entries)
1200                 return -ENOENT;
1201
1202         /* Calculate bucket and index of current iterator */
1203         bucket_idx = *next / RTE_HASH_BUCKET_ENTRIES;
1204         idx = *next % RTE_HASH_BUCKET_ENTRIES;
1205
1206         /* If current position is empty, go to the next one */
1207         while (h->buckets[bucket_idx].signatures[idx].sig == NULL_SIGNATURE) {
1208                 (*next)++;
1209                 /* End of table */
1210                 if (*next == total_entries)
1211                         return -ENOENT;
1212                 bucket_idx = *next / RTE_HASH_BUCKET_ENTRIES;
1213                 idx = *next % RTE_HASH_BUCKET_ENTRIES;
1214         }
1215
1216         /* Get position of entry in key table */
1217         position = h->buckets[bucket_idx].key_idx[idx];
1218         next_key = (struct rte_hash_key *) ((char *)h->key_store +
1219                                 position * h->key_entry_size);
1220         /* Return key and data */
1221         *key = next_key->key;
1222         *data = next_key->pdata;
1223
1224         /* Increment iterator */
1225         (*next)++;
1226
1227         return (position - 1);
1228 }