1
2
3
4
5
6
7
8
9
10
11#ifndef _RTE_CUCKOO_HASH_H_
12#define _RTE_CUCKOO_HASH_H_
13
14#if defined(RTE_ARCH_X86)
15#include "rte_cmp_x86.h"
16#endif
17
18#if defined(RTE_ARCH_ARM64)
19#include "rte_cmp_arm64.h"
20#endif
21
22
23#if defined(RTE_LIBRTE_HASH_DEBUG)
24#define RETURN_IF_TRUE(cond, retval) do { \
25 if (cond) \
26 return retval; \
27} while (0)
28#else
29#define RETURN_IF_TRUE(cond, retval)
30#endif
31
32#if defined(RTE_LIBRTE_HASH_DEBUG)
33#define ERR_IF_TRUE(cond, fmt, args...) do { \
34 if (cond) { \
35 RTE_LOG(ERR, HASH, fmt, ##args); \
36 return; \
37 } \
38} while (0)
39#else
40#define ERR_IF_TRUE(cond, fmt, args...)
41#endif
42
43#include <rte_hash_crc.h>
44#include <rte_jhash.h>
45
46#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
47
48
49
50
51enum cmp_jump_table_case {
52 KEY_CUSTOM = 0,
53 KEY_16_BYTES,
54 KEY_32_BYTES,
55 KEY_48_BYTES,
56 KEY_64_BYTES,
57 KEY_80_BYTES,
58 KEY_96_BYTES,
59 KEY_112_BYTES,
60 KEY_128_BYTES,
61 KEY_OTHER_BYTES,
62 NUM_KEY_CMP_CASES,
63};
64
65
66
67
68
69const rte_hash_cmp_eq_t cmp_jump_table[NUM_KEY_CMP_CASES] = {
70 NULL,
71 rte_hash_k16_cmp_eq,
72 rte_hash_k32_cmp_eq,
73 rte_hash_k48_cmp_eq,
74 rte_hash_k64_cmp_eq,
75 rte_hash_k80_cmp_eq,
76 rte_hash_k96_cmp_eq,
77 rte_hash_k112_cmp_eq,
78 rte_hash_k128_cmp_eq,
79 memcmp
80};
81#else
82
83
84
85
86enum cmp_jump_table_case {
87 KEY_CUSTOM = 0,
88 KEY_OTHER_BYTES,
89 NUM_KEY_CMP_CASES,
90};
91
92
93
94
95
96const rte_hash_cmp_eq_t cmp_jump_table[NUM_KEY_CMP_CASES] = {
97 NULL,
98 memcmp
99};
100
101#endif
102
103
104
105#define RTE_HASH_BUCKET_ENTRIES 8
106
107#if !RTE_IS_POWER_OF_2(RTE_HASH_BUCKET_ENTRIES)
108#error RTE_HASH_BUCKET_ENTRIES must be a power of 2
109#endif
110
111#define NULL_SIGNATURE 0
112
113#define EMPTY_SLOT 0
114
115#define KEY_ALIGNMENT 16
116
117#define LCORE_CACHE_SIZE 64
118
119#define RTE_HASH_BFS_QUEUE_MAX_LEN 1000
120
121#define RTE_XABORT_CUCKOO_PATH_INVALIDED 0x4
122
123#define RTE_HASH_TSX_MAX_RETRY 10
124
125struct lcore_cache {
126 unsigned len;
127 uint32_t objs[LCORE_CACHE_SIZE];
128} __rte_cache_aligned;
129
130
131struct rte_hash_key {
132 union {
133 uintptr_t idata;
134 void *pdata;
135 };
136
137 char key[0];
138};
139
140
141enum rte_hash_sig_compare_function {
142 RTE_HASH_COMPARE_SCALAR = 0,
143 RTE_HASH_COMPARE_SSE,
144 RTE_HASH_COMPARE_NEON,
145 RTE_HASH_COMPARE_NUM
146};
147
148
149struct rte_hash_bucket {
150 uint16_t sig_current[RTE_HASH_BUCKET_ENTRIES];
151
152 uint32_t key_idx[RTE_HASH_BUCKET_ENTRIES];
153
154 uint8_t flag[RTE_HASH_BUCKET_ENTRIES];
155
156 void *next;
157} __rte_cache_aligned;
158
159
160struct rte_hash {
161 char name[RTE_HASH_NAMESIZE];
162 uint32_t entries;
163 uint32_t num_buckets;
164
165 struct rte_ring *free_slots;
166
167
168 struct lcore_cache *local_free_slots;
169
170
171
172 struct rte_hash_rcu_config *hash_rcu_cfg;
173
174 struct rte_rcu_qsbr_dq *dq;
175
176
177
178 uint32_t key_len __rte_cache_aligned;
179
180 uint8_t hw_trans_mem_support;
181
182 uint8_t use_local_cache;
183
184
185
186 uint8_t readwrite_concur_support;
187
188 uint8_t ext_table_support;
189 uint8_t no_free_on_del;
190
191
192
193
194
195 uint8_t readwrite_concur_lf_support;
196
197 uint8_t writer_takes_lock;
198
199 rte_hash_function hash_func;
200 uint32_t hash_func_init_val;
201 rte_hash_cmp_eq_t rte_hash_custom_cmp_eq;
202
203 enum cmp_jump_table_case cmp_jump_table_idx;
204
205 enum rte_hash_sig_compare_function sig_cmp_fn;
206
207 uint32_t bucket_bitmask;
208
209 uint32_t key_entry_size;
210
211 void *key_store;
212 struct rte_hash_bucket *buckets;
213
214
215
216 rte_rwlock_t *readwrite_lock;
217 struct rte_hash_bucket *buckets_ext;
218 struct rte_ring *free_ext_bkts;
219
220
221
222
223
224
225 uint32_t *ext_bkt_to_free;
226 uint32_t *tbl_chng_cnt;
227
228} __rte_cache_aligned;
229
230struct queue_node {
231 struct rte_hash_bucket *bkt;
232 uint32_t cur_bkt_idx;
233
234 struct queue_node *prev;
235 int prev_slot;
236};
237
238
239#define RTE_HASH_RCU_DQ_RECLAIM_MAX 16
240
241#endif
242