Add support for DPDK 17.11
[samplevnf.git] / VNFs / DPPD-PROX / hash_utils.c
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <string.h>
18 #include <rte_hash_crc.h>
19 #include <rte_table_hash.h>
20 #include <rte_version.h>
21
22 #include "hash_utils.h"
23
24 /* These opaque structure definitions were copied from DPDK lib/librte_table/rte_table_hash_key8.c */
25
26 struct rte_bucket_4_8 {
27         /* Cache line 0 */
28         uint64_t signature;
29         uint64_t lru_list;
30         struct rte_bucket_4_8 *next;
31         uint64_t next_valid;
32
33         uint64_t key[4];
34
35         /* Cache line 1 */
36         uint8_t data[0];
37 };
38
39 struct rte_table_hash_key8 {
40 #if RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0)
41         struct rte_table_stats stats;
42 #endif
43         /* Input parameters */
44         uint32_t n_buckets;
45 #if RTE_VERSION < RTE_VERSION_NUM(17,11,0,0)
46         uint32_t n_entries_per_bucket;
47 #endif
48         uint32_t key_size;
49         uint32_t entry_size;
50         uint32_t bucket_size;
51 #if RTE_VERSION < RTE_VERSION_NUM(17,11,0,0)
52         uint32_t signature_offset;
53 #endif
54         uint32_t key_offset;
55 #if RTE_VERSION >= RTE_VERSION_NUM(2,2,0,0)
56         uint64_t key_mask;
57 #endif
58         rte_table_hash_op_hash f_hash;
59         uint64_t seed;
60
61         /* Extendible buckets */
62         uint32_t n_buckets_ext;
63         uint32_t stack_pos;
64         uint32_t *stack;
65
66         /* Lookup table */
67         uint8_t memory[0] __rte_cache_aligned;
68 };
69
70 /* These opaque structure definitions were copied from DPDK lib/librte_table/rte_table_hash_ext.c */
71
72 struct bucket {
73         union {
74                 uintptr_t next;
75                 uint64_t lru_list;
76         };
77         uint16_t sig[4];
78         uint32_t key_pos[4];
79 };
80
81 #define BUCKET_NEXT(bucket)                                             \
82         ((void *) ((bucket)->next & (~1LU)))
83
84 struct grinder {
85         struct bucket *bkt;
86         uint64_t sig;
87         uint64_t match;
88         uint32_t key_index;
89 };
90
91 struct rte_table_hash_ext {
92 #if RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0)
93         struct rte_table_stats stats;
94 #endif
95         /* Input parameters */
96         uint32_t key_size;
97         uint32_t entry_size;
98         uint32_t n_keys;
99         uint32_t n_buckets;
100         uint32_t n_buckets_ext;
101         rte_table_hash_op_hash f_hash;
102         uint64_t seed;
103         uint32_t signature_offset;
104         uint32_t key_offset;
105
106         /* Internal */
107         uint64_t bucket_mask;
108         uint32_t key_size_shl;
109         uint32_t data_size_shl;
110         uint32_t key_stack_tos;
111         uint32_t bkt_ext_stack_tos;
112
113         /* Grinder */
114         struct grinder grinders[64];
115
116         /* Tables */
117         struct bucket *buckets;
118         struct bucket *buckets_ext;
119         uint8_t *key_mem;
120         uint8_t *data_mem;
121         uint32_t *key_stack;
122         uint32_t *bkt_ext_stack;
123
124         /* Table memory */
125         uint8_t memory[0] __rte_cache_aligned;
126 };
127
128 uint64_t get_bucket(void* table, uint32_t bucket_idx, void** key, void** entries)
129 {
130         struct rte_table_hash_ext *t = (struct rte_table_hash_ext *) table;
131         struct bucket *bkt0, *bkt, *bkt_prev;
132         uint64_t sig;
133         uint32_t bkt_index, i;
134         uint8_t n = 0;
135         bkt_index = bucket_idx & t->bucket_mask;
136         bkt0 = &t->buckets[bkt_index];
137         sig = (bucket_idx >> 16) | 1LLU;
138
139         /* Key is present in the bucket */
140         for (bkt = bkt0; bkt != NULL; bkt = BUCKET_NEXT(bkt)) {
141                 for (i = 0; i < 4; i++) {
142                         uint64_t bkt_sig = (uint64_t) bkt->sig[i];
143                         uint32_t bkt_key_index = bkt->key_pos[i];
144                         uint8_t *bkt_key =
145                                 &t->key_mem[bkt_key_index << t->key_size_shl];
146
147                         if (sig == bkt_sig) {
148                                 key[n] = bkt_key;
149                                 entries[n++] = &t->data_mem[bkt_key_index << t->data_size_shl];
150                                 /* Assume no more than 4 entries in total (including extended state) */
151                                 if (n == 4)
152                                         return t->n_buckets;
153                         }
154                 }
155         }
156         return t->n_buckets;
157 }
158
159 uint64_t get_bucket_key8(void* table, uint32_t bucket_idx, void** key, void** entries)
160 {
161         struct rte_bucket_4_8 *bucket, *bucket0;
162         struct rte_table_hash_key8* f = table;
163         uint8_t n = 0;
164
165         bucket0 = (struct rte_bucket_4_8 *) &f->memory[bucket_idx * f->bucket_size];
166         for (bucket = bucket0; bucket != NULL; bucket = bucket->next) {
167                 uint64_t mask;
168
169                 for (uint8_t i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
170                         uint64_t bucket_signature = bucket->signature;
171
172                         if (bucket_signature & mask) {
173                                 key[n] = &bucket->key[i];
174                                 entries[n++] = &bucket->data[i *f->entry_size];
175                                 /* Assume no more than 4 entries
176                                    in total (including extended state) */
177                                 if (n == 4)
178                                         return f->n_buckets;
179                         }
180                 }
181         }
182         return f->n_buckets;
183 }
184
185 uint64_t hash_crc32(void* key, __attribute__((unused))void *key_mask, uint32_t key_size, uint64_t seed)
186 {
187         return rte_hash_crc(key, key_size, seed);
188 }