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