table: add unified params struct and mask-based hash func
[dpdk.git] / lib / librte_table / rte_table_hash_key16.c
index 35b7f10..7f6651c 100644 (file)
@@ -85,7 +85,8 @@ struct rte_table_hash {
        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 */
@@ -129,7 +130,7 @@ rte_table_hash_create_key16_lru(void *params,
        /* 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;
@@ -164,6 +165,14 @@ rte_table_hash_create_key16_lru(void *params,
        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;
 
@@ -178,7 +187,7 @@ rte_table_hash_create_key16_lru(void *params,
 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) {
@@ -198,7 +207,7 @@ rte_table_hash_entry_add_key16_lru(
        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;
@@ -264,7 +273,7 @@ rte_table_hash_entry_delete_key16_lru(
        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;
@@ -335,7 +344,7 @@ rte_table_hash_create_key16_ext(void *params,
        /* 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;
@@ -384,13 +393,21 @@ rte_table_hash_create_key16_ext(void *params,
        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) {
@@ -410,7 +427,7 @@ rte_table_hash_entry_add_key16_ext(
        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;
@@ -487,7 +504,7 @@ rte_table_hash_entry_delete_key16_ext(
        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;
@@ -578,24 +595,33 @@ rte_table_hash_entry_delete_key16_ext(
                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];      \
@@ -609,11 +635,14 @@ rte_table_hash_entry_delete_key16_ext(
        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;                              \
@@ -631,11 +660,14 @@ rte_table_hash_entry_delete_key16_ext(
        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;                              \
@@ -658,12 +690,15 @@ rte_table_hash_entry_delete_key16_ext(
        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;                              \
@@ -682,36 +717,38 @@ rte_table_hash_entry_delete_key16_ext(
 }
 
 #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)                                     \
@@ -720,22 +757,32 @@ rte_table_hash_entry_delete_key16_ext(
        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];    \
@@ -749,13 +796,19 @@ rte_table_hash_entry_delete_key16_ext(
        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;\
@@ -778,13 +831,19 @@ rte_table_hash_entry_delete_key16_ext(
        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;\
@@ -824,6 +883,7 @@ rte_table_hash_lookup_key16_lru(
        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 */
@@ -833,14 +893,15 @@ rte_table_hash_lookup_key16_lru(
                        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;
        }
 
@@ -850,7 +911,7 @@ rte_table_hash_lookup_key16_lru(
         */
        /* Pipeline stage 0 */
        lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
-               pkts_mask);
+               pkts_mask, f);
 
        /* Pipeline feed */
        mbuf10 = mbuf00;
@@ -860,7 +921,7 @@ rte_table_hash_lookup_key16_lru(
 
        /* 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);
@@ -884,7 +945,7 @@ rte_table_hash_lookup_key16_lru(
 
                /* 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);
@@ -930,7 +991,8 @@ rte_table_hash_lookup_key16_lru(
                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() */
 
@@ -952,6 +1014,7 @@ rte_table_hash_lookup_key16_ext(
        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 */
@@ -961,7 +1024,7 @@ rte_table_hash_lookup_key16_ext(
                        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,
@@ -977,7 +1040,7 @@ rte_table_hash_lookup_key16_ext(
         */
        /* Pipeline stage 0 */
        lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
-               pkts_mask);
+               pkts_mask, f);
 
        /* Pipeline feed */
        mbuf10 = mbuf00;
@@ -987,7 +1050,7 @@ rte_table_hash_lookup_key16_ext(
 
        /* 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);
@@ -1011,7 +1074,7 @@ rte_table_hash_lookup_key16_ext(
 
                /* 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);
@@ -1080,14 +1143,15 @@ grind_next_buckets:
        }
 
        *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));
@@ -1103,8 +1167,6 @@ struct rte_table_ops rte_table_hash_key16_lru_ops = {
        .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,
 };
@@ -1114,8 +1176,6 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
        .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,
 };