uint32_t bucket_size;
uint32_t signature_offset;
uint32_t key_offset;
- rte_table_hash_op_hash f_hash;
+ uint64_t key_mask[2];
+ rte_table_hash_op_hash_nomask f_hash;
uint64_t seed;
/* Extendible buckets */
/* Check input parameters */
if ((check_params_create_lru(p) != 0) ||
((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_16) % RTE_CACHE_LINE_SIZE) != 0))
+ ((sizeof(struct rte_bucket_4_16) % 64) != 0))
return NULL;
n_entries_per_bucket = 4;
key_size = 16;
f->f_hash = p->f_hash;
f->seed = p->seed;
+ if (p->key_mask != NULL) {
+ f->key_mask[0] = ((uint64_t *)p->key_mask)[0];
+ f->key_mask[1] = ((uint64_t *)p->key_mask)[1];
+ } else {
+ f->key_mask[0] = 0xFFFFFFFFFFFFFFFFLLU;
+ f->key_mask[1] = 0xFFFFFFFFFFFFFFFFLLU;
+ }
+
for (i = 0; i < n_buckets; i++) {
struct rte_bucket_4_16 *bucket;
static int
rte_table_hash_free_key16_lru(void *table)
{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
+ struct rte_table_hash *f = table;
/* Check input parameters */
if (f == NULL) {
int *key_found,
void **entry_ptr)
{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
+ struct rte_table_hash *f = table;
struct rte_bucket_4_16 *bucket;
uint64_t signature, pos;
uint32_t bucket_index, i;
int *key_found,
void *entry)
{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
+ struct rte_table_hash *f = table;
struct rte_bucket_4_16 *bucket;
uint64_t signature;
uint32_t bucket_index, i;
/* Check input parameters */
if ((check_params_create_ext(p) != 0) ||
((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_16) % RTE_CACHE_LINE_SIZE) != 0))
+ ((sizeof(struct rte_bucket_4_16) % 64) != 0))
return NULL;
n_entries_per_bucket = 4;
for (i = 0; i < n_buckets_ext; i++)
f->stack[i] = i;
+ if (p->key_mask != NULL) {
+ f->key_mask[0] = (((uint64_t *)p->key_mask)[0]);
+ f->key_mask[1] = (((uint64_t *)p->key_mask)[1]);
+ } else {
+ f->key_mask[0] = 0xFFFFFFFFFFFFFFFFLLU;
+ f->key_mask[1] = 0xFFFFFFFFFFFFFFFFLLU;
+ }
+
return f;
}
static int
rte_table_hash_free_key16_ext(void *table)
{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
+ struct rte_table_hash *f = table;
/* Check input parameters */
if (f == NULL) {
int *key_found,
void **entry_ptr)
{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
+ struct rte_table_hash *f = table;
struct rte_bucket_4_16 *bucket0, *bucket, *bucket_prev;
uint64_t signature;
uint32_t bucket_index, i;
int *key_found,
void *entry)
{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
+ struct rte_table_hash *f = table;
struct rte_bucket_4_16 *bucket0, *bucket, *bucket_prev;
uint64_t signature;
uint32_t bucket_index, i;
pos = 3; \
}
-#define lookup1_stage0(pkt0_index, mbuf0, pkts, pkts_mask) \
+#define lookup1_stage0(pkt0_index, mbuf0, pkts, pkts_mask, f) \
{ \
uint64_t pkt_mask; \
+ uint32_t key_offset = f->key_offset;\
\
pkt0_index = __builtin_ctzll(pkts_mask); \
pkt_mask = 1LLU << pkt0_index; \
pkts_mask &= ~pkt_mask; \
\
mbuf0 = pkts[pkt0_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf0, 0)); \
+ rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf0, key_offset));\
}
#define lookup1_stage1(mbuf1, bucket1, f) \
{ \
- uint64_t signature; \
- uint32_t bucket_index; \
+ uint64_t *key; \
+ uint64_t signature = 0; \
+ uint32_t bucket_index; \
+ uint64_t hash_key_buffer[2]; \
+ \
+ key = RTE_MBUF_METADATA_UINT64_PTR(mbuf1, f->key_offset);\
+ \
+ hash_key_buffer[0] = key[0] & f->key_mask[0]; \
+ hash_key_buffer[1] = key[1] & f->key_mask[1]; \
+ signature = f->f_hash(hash_key_buffer, \
+ RTE_TABLE_HASH_KEY_SIZE, f->seed); \
\
- signature = RTE_MBUF_METADATA_UINT32(mbuf1, f->signature_offset);\
bucket_index = signature & (f->n_buckets - 1); \
bucket1 = (struct rte_bucket_4_16 *) \
&f->memory[bucket_index * f->bucket_size]; \
void *a; \
uint64_t pkt_mask; \
uint64_t *key; \
+ uint64_t hash_key_buffer[2]; \
uint32_t pos; \
\
key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+ hash_key_buffer[0] = key[0] & f->key_mask[0]; \
+ hash_key_buffer[1] = key[1] & f->key_mask[1]; \
\
- lookup_key16_cmp(key, bucket2, pos); \
+ lookup_key16_cmp(hash_key_buffer, bucket2, pos); \
\
pkt_mask = (bucket2->signature[pos] & 1LLU) << pkt2_index;\
pkts_mask_out |= pkt_mask; \
void *a; \
uint64_t pkt_mask, bucket_mask; \
uint64_t *key; \
+ uint64_t hash_key_buffer[2]; \
uint32_t pos; \
\
key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+ hash_key_buffer[0] = key[0] & f->key_mask[0]; \
+ hash_key_buffer[1] = key[1] & f->key_mask[1]; \
\
- lookup_key16_cmp(key, bucket2, pos); \
+ lookup_key16_cmp(hash_key_buffer, bucket2, pos); \
\
pkt_mask = (bucket2->signature[pos] & 1LLU) << pkt2_index;\
pkts_mask_out |= pkt_mask; \
void *a; \
uint64_t pkt_mask, bucket_mask; \
uint64_t *key; \
+ uint64_t hash_key_buffer[2]; \
uint32_t pos; \
\
bucket = buckets[pkt_index]; \
key = keys[pkt_index]; \
+ hash_key_buffer[0] = key[0] & f->key_mask[0]; \
+ hash_key_buffer[1] = key[1] & f->key_mask[1]; \
\
- lookup_key16_cmp(key, bucket, pos); \
+ lookup_key16_cmp(hash_key_buffer, bucket, pos); \
\
pkt_mask = (bucket->signature[pos] & 1LLU) << pkt_index;\
pkts_mask_out |= pkt_mask; \
}
#define lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01,\
- pkts, pkts_mask) \
+ pkts, pkts_mask, f) \
{ \
uint64_t pkt00_mask, pkt01_mask; \
+ uint32_t key_offset = f->key_offset; \
\
pkt00_index = __builtin_ctzll(pkts_mask); \
pkt00_mask = 1LLU << pkt00_index; \
pkts_mask &= ~pkt00_mask; \
\
mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, 0)); \
+ rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
\
pkt01_index = __builtin_ctzll(pkts_mask); \
pkt01_mask = 1LLU << pkt01_index; \
pkts_mask &= ~pkt01_mask; \
\
mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, 0)); \
+ rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
}
#define lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,\
- mbuf00, mbuf01, pkts, pkts_mask) \
+ mbuf00, mbuf01, pkts, pkts_mask, f) \
{ \
uint64_t pkt00_mask, pkt01_mask; \
+ uint32_t key_offset = f->key_offset; \
\
pkt00_index = __builtin_ctzll(pkts_mask); \
pkt00_mask = 1LLU << pkt00_index; \
pkts_mask &= ~pkt00_mask; \
\
mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, 0)); \
+ rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset)); \
\
pkt01_index = __builtin_ctzll(pkts_mask); \
if (pkts_mask == 0) \
pkts_mask &= ~pkt01_mask; \
\
mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, 0)); \
+ rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset)); \
}
#define lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f) \
{ \
+ uint64_t *key10, *key11; \
+ uint64_t hash_offset_buffer[2]; \
uint64_t signature10, signature11; \
- uint32_t bucket10_index, bucket11_index; \
+ uint32_t bucket10_index, bucket11_index; \
\
- signature10 = RTE_MBUF_METADATA_UINT32(mbuf10, f->signature_offset);\
+ key10 = RTE_MBUF_METADATA_UINT64_PTR(mbuf10, f->key_offset);\
+ hash_offset_buffer[0] = key10[0] & f->key_mask[0]; \
+ hash_offset_buffer[1] = key10[1] & f->key_mask[1]; \
+ signature10 = f->f_hash(hash_offset_buffer, \
+ RTE_TABLE_HASH_KEY_SIZE, f->seed);\
bucket10_index = signature10 & (f->n_buckets - 1); \
- bucket10 = (struct rte_bucket_4_16 *) \
+ bucket10 = (struct rte_bucket_4_16 *) \
&f->memory[bucket10_index * f->bucket_size]; \
rte_prefetch0(bucket10); \
rte_prefetch0((void *)(((uintptr_t) bucket10) + RTE_CACHE_LINE_SIZE));\
\
- signature11 = RTE_MBUF_METADATA_UINT32(mbuf11, f->signature_offset);\
+ key11 = RTE_MBUF_METADATA_UINT64_PTR(mbuf11, f->key_offset);\
+ hash_offset_buffer[0] = key11[0] & f->key_mask[0]; \
+ hash_offset_buffer[1] = key11[1] & f->key_mask[1]; \
+ signature11 = f->f_hash(hash_offset_buffer, \
+ RTE_TABLE_HASH_KEY_SIZE, f->seed);\
bucket11_index = signature11 & (f->n_buckets - 1); \
bucket11 = (struct rte_bucket_4_16 *) \
&f->memory[bucket11_index * f->bucket_size]; \
void *a20, *a21; \
uint64_t pkt20_mask, pkt21_mask; \
uint64_t *key20, *key21; \
+ uint64_t hash_key_buffer20[2]; \
+ uint64_t hash_key_buffer21[2]; \
uint32_t pos20, pos21; \
\
key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
+ hash_key_buffer20[0] = key20[0] & f->key_mask[0]; \
+ hash_key_buffer20[1] = key20[1] & f->key_mask[1]; \
+ hash_key_buffer21[0] = key21[0] & f->key_mask[0]; \
+ hash_key_buffer21[1] = key21[1] & f->key_mask[1]; \
\
- lookup_key16_cmp(key20, bucket20, pos20); \
- lookup_key16_cmp(key21, bucket21, pos21); \
+ lookup_key16_cmp(hash_key_buffer20, bucket20, pos20); \
+ lookup_key16_cmp(hash_key_buffer21, bucket21, pos21); \
\
pkt20_mask = (bucket20->signature[pos20] & 1LLU) << pkt20_index;\
pkt21_mask = (bucket21->signature[pos21] & 1LLU) << pkt21_index;\
void *a20, *a21; \
uint64_t pkt20_mask, pkt21_mask, bucket20_mask, bucket21_mask;\
uint64_t *key20, *key21; \
+ uint64_t hash_key_buffer20[2]; \
+ uint64_t hash_key_buffer21[2]; \
uint32_t pos20, pos21; \
\
key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
+ hash_key_buffer20[0] = key20[0] & f->key_mask[0]; \
+ hash_key_buffer20[1] = key20[1] & f->key_mask[1]; \
+ hash_key_buffer21[0] = key21[0] & f->key_mask[0]; \
+ hash_key_buffer21[1] = key21[1] & f->key_mask[1]; \
\
- lookup_key16_cmp(key20, bucket20, pos20); \
- lookup_key16_cmp(key21, bucket21, pos21); \
+ lookup_key16_cmp(hash_key_buffer20, bucket20, pos20); \
+ lookup_key16_cmp(hash_key_buffer21, bucket21, pos21); \
\
pkt20_mask = (bucket20->signature[pos20] & 1LLU) << pkt20_index;\
pkt21_mask = (bucket21->signature[pos21] & 1LLU) << pkt21_index;\
uint64_t pkts_mask_out = 0;
__rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+
RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(f, n_pkts_in);
/* Cannot run the pipeline with less than 5 packets */
struct rte_mbuf *mbuf;
uint32_t pkt_index;
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+ lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
lookup1_stage1(mbuf, bucket, f);
lookup1_stage2_lru(pkt_index, mbuf, bucket,
pkts_mask_out, entries, f);
}
*lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - __builtin_popcountll(pkts_mask_out));
+ RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in -
+ __builtin_popcountll(pkts_mask_out));
return 0;
}
*/
/* Pipeline stage 0 */
lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask);
+ pkts_mask, f);
/* Pipeline feed */
mbuf10 = mbuf00;
/* Pipeline stage 0 */
lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask);
+ pkts_mask, f);
/* Pipeline stage 1 */
lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
/* Pipeline stage 0 */
lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask);
+ mbuf00, mbuf01, pkts, pkts_mask, f);
/* Pipeline stage 1 */
lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
bucket20, bucket21, pkts_mask_out, entries, f);
*lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - __builtin_popcountll(pkts_mask_out));
+ RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in -
+ __builtin_popcountll(pkts_mask_out));
return 0;
} /* rte_table_hash_lookup_key16_lru() */
uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];
__rte_unused uint32_t n_pkts_in = __builtin_popcountll(pkts_mask);
+
RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(f, n_pkts_in);
/* Cannot run the pipeline with less than 5 packets */
struct rte_mbuf *mbuf;
uint32_t pkt_index;
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+ lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
lookup1_stage1(mbuf, bucket, f);
lookup1_stage2_ext(pkt_index, mbuf, bucket,
pkts_mask_out, entries, buckets_mask,
*/
/* Pipeline stage 0 */
lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask);
+ pkts_mask, f);
/* Pipeline feed */
mbuf10 = mbuf00;
/* Pipeline stage 0 */
lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask);
+ pkts_mask, f);
/* Pipeline stage 1 */
lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
/* Pipeline stage 0 */
lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask);
+ mbuf00, mbuf01, pkts, pkts_mask, f);
/* Pipeline stage 1 */
lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
}
*lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - __builtin_popcountll(pkts_mask_out));
+ RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in -
+ __builtin_popcountll(pkts_mask_out));
return 0;
} /* rte_table_hash_lookup_key16_ext() */
static int
rte_table_hash_key16_stats_read(void *table, struct rte_table_stats *stats, int clear)
{
- struct rte_table_hash *t = (struct rte_table_hash *) table;
+ struct rte_table_hash *t = table;
if (stats != NULL)
memcpy(stats, &t->stats, sizeof(t->stats));
.f_free = rte_table_hash_free_key16_lru,
.f_add = rte_table_hash_entry_add_key16_lru,
.f_delete = rte_table_hash_entry_delete_key16_lru,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key16_lru,
.f_stats = rte_table_hash_key16_stats_read,
};
.f_free = rte_table_hash_free_key16_ext,
.f_add = rte_table_hash_entry_add_key16_ext,
.f_delete = rte_table_hash_entry_delete_key16_ext,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key16_ext,
.f_stats = rte_table_hash_key16_stats_read,
};