hash: replace with cuckoo hash implementation
[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 /* Search for an entry that can be pushed to its alternative location */
375 static inline int
376 make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
377 {
378         unsigned i, j;
379         int ret;
380         uint32_t next_bucket_idx;
381         struct rte_hash_bucket *next_bkt[RTE_HASH_BUCKET_ENTRIES];
382
383         /*
384          * Push existing item (search for bucket with space in
385          * alternative locations) to its alternative location
386          */
387         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
388                 /* Search for space in alternative locations */
389                 next_bucket_idx = bkt->signatures[i].alt & h->bucket_bitmask;
390                 next_bkt[i] = &h->buckets[next_bucket_idx];
391                 for (j = 0; j < RTE_HASH_BUCKET_ENTRIES; j++) {
392                         if (next_bkt[i]->signatures[j].sig == NULL_SIGNATURE)
393                                 break;
394                 }
395
396                 if (j != RTE_HASH_BUCKET_ENTRIES)
397                         break;
398         }
399
400         /* Alternative location has spare room (end of recursive function) */
401         if (i != RTE_HASH_BUCKET_ENTRIES) {
402                 next_bkt[i]->signatures[j].alt = bkt->signatures[i].current;
403                 next_bkt[i]->signatures[j].current = bkt->signatures[i].alt;
404                 next_bkt[i]->key_idx[j] = bkt->key_idx[i];
405                 return i;
406         }
407
408         /* Pick entry that has not been pushed yet */
409         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++)
410                 if (bkt->flag[i] == 0)
411                         break;
412
413         /* All entries have been pushed, so entry cannot be added */
414         if (i == RTE_HASH_BUCKET_ENTRIES) {
415                 /* Reset flag */
416                 bkt->flag[i] = 0;
417                 return -ENOSPC;
418         }
419
420         /* Set flag to indicate that this entry is going to be pushed */
421         bkt->flag[i] = 1;
422         /* Need room in alternative bucket to insert the pushed entry */
423         ret = make_space_bucket(h, next_bkt[i]);
424         /*
425          * After recursive function.
426          * Clear flags and insert the pushed entry
427          * in its alternative location if successful,
428          * or return error
429          */
430         bkt->flag[i] = 0;
431         if (ret >= 0) {
432                 next_bkt[i]->signatures[ret].alt = bkt->signatures[i].current;
433                 next_bkt[i]->signatures[ret].current = bkt->signatures[i].alt;
434                 next_bkt[i]->key_idx[ret] = bkt->key_idx[i];
435                 return i;
436         } else
437                 return ret;
438
439 }
440
441 static inline int32_t
442 __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,
443                                                 hash_sig_t sig)
444 {
445         hash_sig_t alt_hash;
446         uint32_t prim_bucket_idx, sec_bucket_idx;
447         unsigned i;
448         struct rte_hash_bucket *prim_bkt, *sec_bkt;
449         void *new_k, *k, *keys = h->key_store;
450         void *slot_id;
451         uint32_t new_idx;
452         int ret;
453
454         prim_bucket_idx = sig & h->bucket_bitmask;
455         prim_bkt = &h->buckets[prim_bucket_idx];
456         rte_prefetch0(prim_bkt);
457
458         alt_hash = rte_hash_secondary_hash(sig);
459         sec_bucket_idx = alt_hash & h->bucket_bitmask;
460         sec_bkt = &h->buckets[sec_bucket_idx];
461         rte_prefetch0(sec_bkt);
462
463         /* Get a new slot for storing the new key */
464         if (rte_ring_sc_dequeue(h->free_slots, &slot_id) != 0)
465                 return -ENOSPC;
466         new_k = RTE_PTR_ADD(keys, (uintptr_t)slot_id * h->key_entry_size);
467         rte_prefetch0(new_k);
468         new_idx = (uint32_t)((uintptr_t) slot_id);
469
470         /* Check if key is already inserted in primary location */
471         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
472                 if (prim_bkt->signatures[i].current == sig &&
473                                 prim_bkt->signatures[i].alt == alt_hash)  {
474                         k = (char *)keys + prim_bkt->key_idx[i] * h->key_entry_size;
475                         if (h->rte_hash_cmp_eq(key, k, h->key_len) == 0) {
476                                 rte_ring_sp_enqueue(h->free_slots, &slot_id);
477                                 /*
478                                  * Return index where key is stored,
479                                  * substracting the first dummy index
480                                  */
481                                 return (prim_bkt->key_idx[i] - 1);
482                         }
483                 }
484         }
485
486         /* Check if key is already inserted in secondary location */
487         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
488                 if (sec_bkt->signatures[i].alt == sig &&
489                                 sec_bkt->signatures[i].current == alt_hash)  {
490                         k = (char *)keys + sec_bkt->key_idx[i] * h->key_entry_size;
491                         if (h->rte_hash_cmp_eq(key, k, h->key_len) == 0) {
492                                 rte_ring_sp_enqueue(h->free_slots, &slot_id);
493                                 /*
494                                  * Return index where key is stored,
495                                  * substracting the first dummy index
496                                  */
497                                 return (sec_bkt->key_idx[i] - 1);
498                         }
499                 }
500         }
501
502         /* Copy key */
503         rte_memcpy(new_k, key, h->key_len);
504
505         /* Insert new entry is there is room in the primary bucket */
506         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
507                 /* Check if slot is available */
508                 if (likely(prim_bkt->signatures[i].sig == NULL_SIGNATURE)) {
509                         prim_bkt->signatures[i].current = sig;
510                         prim_bkt->signatures[i].alt = alt_hash;
511                         prim_bkt->key_idx[i] = new_idx;
512                         return new_idx - 1;
513                 }
514         }
515
516         /* Primary bucket is full, so we need to make space for new entry */
517         ret = make_space_bucket(h, prim_bkt);
518         /*
519          * After recursive function.
520          * Insert the new entry in the position of the pushed entry
521          * if successful or return error and
522          * store the new slot back in the ring
523          */
524         if (ret >= 0) {
525                 prim_bkt->signatures[ret].current = sig;
526                 prim_bkt->signatures[ret].alt = alt_hash;
527                 prim_bkt->key_idx[ret] = new_idx;
528                 return (new_idx - 1);
529         }
530
531         /* Error in addition, store new slot back in the ring and return error */
532         rte_ring_sp_enqueue(h->free_slots,
533                 (void *)((uintptr_t) new_idx));
534         return ret;
535
536 }
537
538 int32_t
539 rte_hash_add_key_with_hash(const struct rte_hash *h,
540                         const void *key, hash_sig_t sig)
541 {
542         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
543         return __rte_hash_add_key_with_hash(h, key, sig);
544 }
545
546 int32_t
547 rte_hash_add_key(const struct rte_hash *h, const void *key)
548 {
549         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
550         return __rte_hash_add_key_with_hash(h, key, rte_hash_hash(h, key));
551 }
552
553 static inline int32_t
554 __rte_hash_lookup_with_hash(const struct rte_hash *h, const void *key,
555                                         hash_sig_t sig)
556 {
557         uint32_t bucket_idx;
558         hash_sig_t alt_hash;
559         unsigned i;
560         struct rte_hash_bucket *bkt;
561         void *k, *keys = h->key_store;
562
563         bucket_idx = sig & h->bucket_bitmask;
564         bkt = &h->buckets[bucket_idx];
565
566         /* Check if key is in primary location */
567         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
568                 if (bkt->signatures[i].current == sig &&
569                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
570                         k = (char *)keys + bkt->key_idx[i] * h->key_entry_size;
571                         if (h->rte_hash_cmp_eq(key, k, h->key_len) == 0)
572                                 /*
573                                  * Return index where key is stored,
574                                  * substracting the first dummy index
575                                  */
576                                 return (bkt->key_idx[i] - 1);
577                 }
578         }
579
580         /* Calculate secondary hash */
581         alt_hash = rte_hash_secondary_hash(sig);
582         bucket_idx = alt_hash & h->bucket_bitmask;
583         bkt = &h->buckets[bucket_idx];
584
585         /* Check if key is in secondary location */
586         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
587                 if (bkt->signatures[i].current == alt_hash &&
588                                 bkt->signatures[i].alt == sig) {
589                         k = (char *)keys + bkt->key_idx[i] * h->key_entry_size;
590                         if (h->rte_hash_cmp_eq(key, k, h->key_len) == 0)
591                                 /*
592                                  * Return index where key is stored,
593                                  * substracting the first dummy index
594                                  */
595                                 return (bkt->key_idx[i] - 1);
596                 }
597         }
598
599         return -ENOENT;
600 }
601
602 int32_t
603 rte_hash_lookup_with_hash(const struct rte_hash *h,
604                         const void *key, hash_sig_t sig)
605 {
606         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
607         return __rte_hash_lookup_with_hash(h, key, sig);
608 }
609
610 int32_t
611 rte_hash_lookup(const struct rte_hash *h, const void *key)
612 {
613         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
614         return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key));
615 }
616
617 static inline int32_t
618 __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,
619                                                 hash_sig_t sig)
620 {
621         uint32_t bucket_idx;
622         hash_sig_t alt_hash;
623         unsigned i;
624         struct rte_hash_bucket *bkt;
625         void *k, *keys = h->key_store;
626
627         bucket_idx = sig & h->bucket_bitmask;
628         bkt = &h->buckets[bucket_idx];
629
630         /* Check if key is in primary location */
631         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
632                 if (bkt->signatures[i].current == sig &&
633                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
634                         k = (char *)keys + bkt->key_idx[i] * h->key_entry_size;
635                         if (h->rte_hash_cmp_eq(key, k, h->key_len) == 0) {
636                                 bkt->signatures[i].sig = NULL_SIGNATURE;
637                                 rte_ring_sp_enqueue(h->free_slots,
638                                                 (void *)((uintptr_t)bkt->key_idx[i]));
639                                 /*
640                                  * Return index where key is stored,
641                                  * substracting the first dummy index
642                                  */
643                                 return (bkt->key_idx[i] - 1);
644                         }
645                 }
646         }
647
648         /* Calculate secondary hash */
649         alt_hash = rte_hash_secondary_hash(sig);
650         bucket_idx = alt_hash & h->bucket_bitmask;
651         bkt = &h->buckets[bucket_idx];
652
653         /* Check if key is in secondary location */
654         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
655                 if (bkt->signatures[i].current == alt_hash &&
656                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
657                         k = (char *)keys + bkt->key_idx[i] * h->key_entry_size;
658                         if (h->rte_hash_cmp_eq(key, k, h->key_len) == 0) {
659                                 bkt->signatures[i].sig = NULL_SIGNATURE;
660                                 rte_ring_sp_enqueue(h->free_slots,
661                                                 (void *)((uintptr_t)bkt->key_idx[i]));
662                                 /*
663                                  * Return index where key is stored,
664                                  * substracting the first dummy index
665                                  */
666                                 return (bkt->key_idx[i] - 1);
667                         }
668                 }
669         }
670
671         return -ENOENT;
672 }
673
674 int32_t
675 rte_hash_del_key_with_hash(const struct rte_hash *h,
676                         const void *key, hash_sig_t sig)
677 {
678         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
679         return __rte_hash_del_key_with_hash(h, key, sig);
680 }
681
682 int32_t
683 rte_hash_del_key(const struct rte_hash *h, const void *key)
684 {
685         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
686         return __rte_hash_del_key_with_hash(h, key, rte_hash_hash(h, key));
687 }
688
689 /* Lookup bulk stage 0: Prefetch input key */
690 static inline void
691 lookup_stage0(unsigned *idx, uint64_t *lookup_mask,
692                 const void * const *keys)
693 {
694         *idx = __builtin_ctzl(*lookup_mask);
695         if (*lookup_mask == 0)
696                 *idx = 0;
697
698         rte_prefetch0(keys[*idx]);
699         *lookup_mask &= ~(1llu << *idx);
700 }
701
702 /*
703  * Lookup bulk stage 1: Calculate primary/secondary hashes
704  * and prefetch primary/secondary buckets
705  */
706 static inline void
707 lookup_stage1(unsigned idx, hash_sig_t *prim_hash, hash_sig_t *sec_hash,
708                 const struct rte_hash_bucket **primary_bkt,
709                 const struct rte_hash_bucket **secondary_bkt,
710                 hash_sig_t *hash_vals, const void * const *keys,
711                 const struct rte_hash *h)
712 {
713         *prim_hash = rte_hash_hash(h, keys[idx]);
714         hash_vals[idx] = *prim_hash;
715         *sec_hash = rte_hash_secondary_hash(*prim_hash);
716
717         *primary_bkt = &h->buckets[*prim_hash & h->bucket_bitmask];
718         *secondary_bkt = &h->buckets[*sec_hash & h->bucket_bitmask];
719
720         rte_prefetch0(*primary_bkt);
721         rte_prefetch0(*secondary_bkt);
722 }
723
724 /*
725  * Lookup bulk stage 2:  Search for match hashes in primary/secondary locations
726  * and prefetch first key slot
727  */
728 static inline void
729 lookup_stage2(unsigned idx, hash_sig_t prim_hash, hash_sig_t sec_hash,
730                 const struct rte_hash_bucket *prim_bkt,
731                 const struct rte_hash_bucket *sec_bkt,
732                 const void **key_slot, int32_t *positions,
733                 uint64_t *extra_hits_mask, const void *keys,
734                 const struct rte_hash *h)
735 {
736         unsigned prim_hash_matches, sec_hash_matches, key_idx, i;
737         unsigned total_hash_matches;
738
739         prim_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
740         sec_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
741         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
742                 prim_hash_matches |= ((prim_hash == prim_bkt->signatures[i].current) << i);
743                 sec_hash_matches |= ((sec_hash == sec_bkt->signatures[i].current) << i);
744         }
745
746         key_idx = prim_bkt->key_idx[__builtin_ctzl(prim_hash_matches)];
747         if (key_idx == 0)
748                 key_idx = sec_bkt->key_idx[__builtin_ctzl(sec_hash_matches)];
749
750         total_hash_matches = (prim_hash_matches |
751                                 (sec_hash_matches << (RTE_HASH_BUCKET_ENTRIES + 1)));
752         *key_slot = (const char *)keys + key_idx * h->key_entry_size;
753
754         rte_prefetch0(*key_slot);
755         /*
756          * Return index where key is stored,
757          * substracting the first dummy index
758          */
759         positions[idx] = (key_idx - 1);
760
761         *extra_hits_mask |= (uint64_t)(__builtin_popcount(total_hash_matches) > 3) << idx;
762
763 }
764
765
766 /* Lookup bulk stage 3: Check if key matches, update hit mask */
767 static inline void
768 lookup_stage3(unsigned idx, const void *key_slot, const void * const *keys,
769                 uint64_t *hits, const struct rte_hash *h)
770 {
771         unsigned hit;
772
773         hit = !h->rte_hash_cmp_eq(key_slot, keys[idx], h->key_len);
774         *hits |= (uint64_t)(hit) << idx;
775 }
776
777 static inline void
778 __rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
779                       uint32_t num_keys, int32_t *positions)
780 {
781         uint64_t hits = 0;
782         uint64_t extra_hits_mask = 0;
783         uint64_t lookup_mask, miss_mask;
784         unsigned idx;
785         const void *key_store = h->key_store;
786         hash_sig_t hash_vals[RTE_HASH_LOOKUP_BULK_MAX];
787
788         unsigned idx00, idx01, idx10, idx11, idx20, idx21, idx30, idx31;
789         const struct rte_hash_bucket *primary_bkt10, *primary_bkt11;
790         const struct rte_hash_bucket *secondary_bkt10, *secondary_bkt11;
791         const struct rte_hash_bucket *primary_bkt20, *primary_bkt21;
792         const struct rte_hash_bucket *secondary_bkt20, *secondary_bkt21;
793         const void *k_slot20, *k_slot21, *k_slot30, *k_slot31;
794         hash_sig_t primary_hash10, primary_hash11;
795         hash_sig_t secondary_hash10, secondary_hash11;
796         hash_sig_t primary_hash20, primary_hash21;
797         hash_sig_t secondary_hash20, secondary_hash21;
798
799         lookup_mask = (uint64_t) -1 >> (64 - num_keys);
800         miss_mask = lookup_mask;
801
802         lookup_stage0(&idx00, &lookup_mask, keys);
803         lookup_stage0(&idx01, &lookup_mask, keys);
804
805         idx10 = idx00, idx11 = idx01;
806
807         lookup_stage0(&idx00, &lookup_mask, keys);
808         lookup_stage0(&idx01, &lookup_mask, keys);
809         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
810                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
811         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
812                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
813
814         primary_bkt20 = primary_bkt10;
815         primary_bkt21 = primary_bkt11;
816         secondary_bkt20 = secondary_bkt10;
817         secondary_bkt21 = secondary_bkt11;
818         primary_hash20 = primary_hash10;
819         primary_hash21 = primary_hash11;
820         secondary_hash20 = secondary_hash10;
821         secondary_hash21 = secondary_hash11;
822         idx20 = idx10, idx21 = idx11;
823         idx10 = idx00, idx11 = idx01;
824
825         lookup_stage0(&idx00, &lookup_mask, keys);
826         lookup_stage0(&idx01, &lookup_mask, keys);
827         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
828                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
829         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
830                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
831         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
832                         secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
833                         key_store, h);
834         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
835                         secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
836                         key_store, h);
837
838         while (lookup_mask) {
839                 k_slot30 = k_slot20, k_slot31 = k_slot21;
840                 idx30 = idx20, idx31 = idx21;
841                 primary_bkt20 = primary_bkt10;
842                 primary_bkt21 = primary_bkt11;
843                 secondary_bkt20 = secondary_bkt10;
844                 secondary_bkt21 = secondary_bkt11;
845                 primary_hash20 = primary_hash10;
846                 primary_hash21 = primary_hash11;
847                 secondary_hash20 = secondary_hash10;
848                 secondary_hash21 = secondary_hash11;
849                 idx20 = idx10, idx21 = idx11;
850                 idx10 = idx00, idx11 = idx01;
851
852                 lookup_stage0(&idx00, &lookup_mask, keys);
853                 lookup_stage0(&idx01, &lookup_mask, keys);
854                 lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
855                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
856                 lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
857                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
858                 lookup_stage2(idx20, primary_hash20, secondary_hash20,
859                         primary_bkt20, secondary_bkt20, &k_slot20, positions,
860                         &extra_hits_mask, key_store, h);
861                 lookup_stage2(idx21, primary_hash21, secondary_hash21,
862                         primary_bkt21, secondary_bkt21, &k_slot21, positions,
863                         &extra_hits_mask, key_store, h);
864                 lookup_stage3(idx30, k_slot30, keys, &hits, h);
865                 lookup_stage3(idx31, k_slot31, keys, &hits, h);
866         }
867
868         k_slot30 = k_slot20, k_slot31 = k_slot21;
869         idx30 = idx20, idx31 = idx21;
870         primary_bkt20 = primary_bkt10;
871         primary_bkt21 = primary_bkt11;
872         secondary_bkt20 = secondary_bkt10;
873         secondary_bkt21 = secondary_bkt11;
874         primary_hash20 = primary_hash10;
875         primary_hash21 = primary_hash11;
876         secondary_hash20 = secondary_hash10;
877         secondary_hash21 = secondary_hash11;
878         idx20 = idx10, idx21 = idx11;
879         idx10 = idx00, idx11 = idx01;
880
881         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
882                 &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
883         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
884                 &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
885         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
886                 secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
887                 key_store, h);
888         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
889                 secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
890                 key_store, h);
891         lookup_stage3(idx30, k_slot30, keys, &hits, h);
892         lookup_stage3(idx31, k_slot31, keys, &hits, h);
893
894         k_slot30 = k_slot20, k_slot31 = k_slot21;
895         idx30 = idx20, idx31 = idx21;
896         primary_bkt20 = primary_bkt10;
897         primary_bkt21 = primary_bkt11;
898         secondary_bkt20 = secondary_bkt10;
899         secondary_bkt21 = secondary_bkt11;
900         primary_hash20 = primary_hash10;
901         primary_hash21 = primary_hash11;
902         secondary_hash20 = secondary_hash10;
903         secondary_hash21 = secondary_hash11;
904         idx20 = idx10, idx21 = idx11;
905
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
918         lookup_stage3(idx30, k_slot30, keys, &hits, h);
919         lookup_stage3(idx31, k_slot31, keys, &hits, h);
920
921         /* ignore any items we have already found */
922         extra_hits_mask &= ~hits;
923
924         if (unlikely(extra_hits_mask)) {
925                 /* run a single search for each remaining item */
926                 do {
927                         idx = __builtin_ctzl(extra_hits_mask);
928                         positions[idx] = rte_hash_lookup_with_hash(h, keys[idx],
929                                                         hash_vals[idx]);
930                         extra_hits_mask &= ~(1llu << idx);
931                         if (positions[idx] >= 0)
932                                 hits |= 1llu << idx;
933                 } while (extra_hits_mask);
934         }
935
936         miss_mask &= ~hits;
937         if (unlikely(miss_mask)) {
938                 do {
939                         idx = __builtin_ctzl(miss_mask);
940                         positions[idx] = -ENOENT;
941                         miss_mask &= ~(1llu << idx);
942                 } while (miss_mask);
943         }
944 }
945
946 int
947 rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
948                       uint32_t num_keys, int32_t *positions)
949 {
950         RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) ||
951                         (num_keys > RTE_HASH_LOOKUP_BULK_MAX) ||
952                         (positions == NULL)), -EINVAL);
953
954         __rte_hash_lookup_bulk(h, keys, num_keys, positions);
955         return 0;
956 }
957
958 /* Functions to compare multiple of 16 byte keys (up to 128 bytes) */
959 static int
960 rte_hash_k16_cmp_eq(const void *key1, const void *key2, size_t key_len __rte_unused)
961 {
962         const __m128i k1 = _mm_loadu_si128((const __m128i *) key1);
963         const __m128i k2 = _mm_loadu_si128((const __m128i *) key2);
964         const __m128i x = _mm_xor_si128(k1, k2);
965
966         return !_mm_test_all_zeros(x, x);
967 }
968
969 static int
970 rte_hash_k32_cmp_eq(const void *key1, const void *key2, size_t key_len)
971 {
972         return rte_hash_k16_cmp_eq(key1, key2, key_len) ||
973                 rte_hash_k16_cmp_eq((const char *) key1 + 16,
974                                 (const char *) key2 + 16, key_len);
975 }
976
977 static int
978 rte_hash_k48_cmp_eq(const void *key1, const void *key2, size_t key_len)
979 {
980         return rte_hash_k16_cmp_eq(key1, key2, key_len) ||
981                 rte_hash_k16_cmp_eq((const char *) key1 + 16,
982                                 (const char *) key2 + 16, key_len) ||
983                 rte_hash_k16_cmp_eq((const char *) key1 + 32,
984                                 (const char *) key2 + 32, key_len);
985 }
986
987 static int
988 rte_hash_k64_cmp_eq(const void *key1, const void *key2, size_t key_len)
989 {
990         return rte_hash_k32_cmp_eq(key1, key2, key_len) ||
991                 rte_hash_k32_cmp_eq((const char *) key1 + 32,
992                                 (const char *) key2 + 32, key_len);
993 }
994
995 static int
996 rte_hash_k80_cmp_eq(const void *key1, const void *key2, size_t key_len)
997 {
998         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
999                 rte_hash_k16_cmp_eq((const char *) key1 + 64,
1000                                 (const char *) key2 + 64, key_len);
1001 }
1002
1003 static int
1004 rte_hash_k96_cmp_eq(const void *key1, const void *key2, size_t key_len)
1005 {
1006         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
1007                 rte_hash_k32_cmp_eq((const char *) key1 + 64,
1008                                 (const char *) key2 + 64, key_len);
1009 }
1010
1011 static int
1012 rte_hash_k112_cmp_eq(const void *key1, const void *key2, size_t key_len)
1013 {
1014         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
1015                 rte_hash_k32_cmp_eq((const char *) key1 + 64,
1016                                 (const char *) key2 + 64, key_len) ||
1017                 rte_hash_k16_cmp_eq((const char *) key1 + 96,
1018                                 (const char *) key2 + 96, key_len);
1019 }
1020
1021 static int
1022 rte_hash_k128_cmp_eq(const void *key1, const void *key2, size_t key_len)
1023 {
1024         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
1025                 rte_hash_k64_cmp_eq((const char *) key1 + 64,
1026                                 (const char *) key2 + 64, key_len);
1027 }