DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key
@ 2015-09-25 22:33 roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters roy.fan.zhang
                   ` (8 more replies)
  0 siblings, 9 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patchset links to ABI change announced for librte_table. Key_mask
parameters has been added to the hash table parameter structure for
8-byte key and 16-byte key extendible bucket and LRU tables.

Fan Zhang (8):
  librte_table: add key_mask parameter to 8-byte key hash parameters
  librte_table: add key_mask parameter to 16-byte key hash parameters
  librte_table: add 16 byte hash table operations with computed lookup
  app/test: modify app/test_table_combined and app/test_table_tables
  app/test-pipeline: modify pipeline test
  example/ip_pipeline: add parse_hex_string for internal use
  example/ip_pipeline/pipeline: update flow_classification pipeline
  librte_table: modify release notes and deprecation notice

 app/test-pipeline/pipeline_hash.c                  |   4 +
 app/test/test_table_combined.c                     |   4 +
 app/test/test_table_tables.c                       |   6 +-
 doc/guides/rel_notes/deprecation.rst               |   3 -
 doc/guides/rel_notes/release_2_2.rst               |   5 +-
 examples/ip_pipeline/config_parse.c                |  70 ++++
 examples/ip_pipeline/pipeline.h                    |   4 +
 .../pipeline/pipeline_flow_classification_be.c     |  56 ++-
 lib/librte_table/Makefile                          |   2 +-
 lib/librte_table/rte_table_hash.h                  |  20 +
 lib/librte_table/rte_table_hash_key16.c            | 411 ++++++++++++++++++++-
 lib/librte_table/rte_table_hash_key8.c             |  54 ++-
 12 files changed, 608 insertions(+), 31 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 2/8] librte_table: add key_mask parameter to 16-byte " roy.fan.zhang
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch relates to ABI change proposed for librte_table. key_mask
parameter is added for 8-byte key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_table/rte_table_hash.h      |  6 ++++
 lib/librte_table/rte_table_hash_key8.c | 54 +++++++++++++++++++++++++++-------
 2 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index 9181942..ef65355 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -196,6 +196,9 @@ struct rte_table_hash_key8_lru_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** LRU hash table operations for pre-computed key signature */
@@ -226,6 +229,9 @@ struct rte_table_hash_key8_ext_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** Extendible bucket hash table operations for pre-computed key signature */
diff --git a/lib/librte_table/rte_table_hash_key8.c b/lib/librte_table/rte_table_hash_key8.c
index b351a49..ccb20cf 100644
--- a/lib/librte_table/rte_table_hash_key8.c
+++ b/lib/librte_table/rte_table_hash_key8.c
@@ -82,6 +82,7 @@ struct rte_table_hash {
 	uint32_t bucket_size;
 	uint32_t signature_offset;
 	uint32_t key_offset;
+	uint64_t key_mask;
 	rte_table_hash_op_hash f_hash;
 	uint64_t seed;
 
@@ -160,6 +161,11 @@ rte_table_hash_create_key8_lru(void *params, int socket_id, uint32_t entry_size)
 	f->f_hash = p->f_hash;
 	f->seed = p->seed;
 
+	if (p->key_mask != NULL)
+		f->key_mask = ((uint64_t *)p->key_mask)[0];
+	else
+		f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
+
 	for (i = 0; i < n_buckets; i++) {
 		struct rte_bucket_4_8 *bucket;
 
@@ -372,6 +378,11 @@ rte_table_hash_create_key8_ext(void *params, int socket_id, uint32_t entry_size)
 	f->stack = (uint32_t *)
 		&f->memory[(n_buckets + n_buckets_ext) * f->bucket_size];
 
+	if (p->key_mask != NULL)
+		f->key_mask = ((uint64_t *)p->key_mask)[0];
+	else
+		f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
+
 	for (i = 0; i < n_buckets_ext; i++)
 		f->stack[i] = i;
 
@@ -586,9 +597,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t *key;						\
 	uint64_t signature;					\
 	uint32_t bucket_index;					\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf1, f->key_offset);\
-	signature = f->f_hash(key, RTE_TABLE_HASH_KEY_SIZE, f->seed);\
+	hash_key_buffer = *key & f->key_mask;			\
+	signature = f->f_hash(&hash_key_buffer,			\
+		RTE_TABLE_HASH_KEY_SIZE, f->seed);		\
 	bucket_index = signature & (f->n_buckets - 1);		\
 	bucket1 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket_index * f->bucket_size];	\
@@ -602,10 +616,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask;					\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+	hash_key_buffer = key[0] & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket2, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket2, pos);	\
 								\
 	pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -624,10 +640,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask, bucket_mask;				\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+	hash_key_buffer = *key & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket2, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket2, pos);	\
 								\
 	pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -651,11 +669,13 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask, bucket_mask;				\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	bucket = buckets[pkt_index];				\
 	key = keys[pkt_index];					\
+	hash_key_buffer = (*key) & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket, pos);	\
 								\
 	pkt_mask = ((bucket->signature >> pos) & 1LLU) << pkt_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -736,6 +756,8 @@ rte_table_hash_entry_delete_key8_ext(
 #define lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f)\
 {								\
 	uint64_t *key10, *key11;				\
+	uint64_t hash_offset_buffer10;				\
+	uint64_t hash_offset_buffer11;				\
 	uint64_t signature10, signature11;			\
 	uint32_t bucket10_index, bucket11_index;		\
 	rte_table_hash_op_hash f_hash = f->f_hash;		\
@@ -744,14 +766,18 @@ rte_table_hash_entry_delete_key8_ext(
 								\
 	key10 = RTE_MBUF_METADATA_UINT64_PTR(mbuf10, key_offset);\
 	key11 = RTE_MBUF_METADATA_UINT64_PTR(mbuf11, key_offset);\
+	hash_offset_buffer10 = *key10 & f->key_mask;		\
+	hash_offset_buffer11 = *key11 & f->key_mask;		\
 								\
-	signature10 = f_hash(key10, RTE_TABLE_HASH_KEY_SIZE, seed);\
+	signature10 = f_hash(&hash_offset_buffer10,		\
+		RTE_TABLE_HASH_KEY_SIZE, seed);			\
 	bucket10_index = signature10 & (f->n_buckets - 1);	\
 	bucket10 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket10_index * f->bucket_size];	\
 	rte_prefetch0(bucket10);				\
 								\
-	signature11 = f_hash(key11, RTE_TABLE_HASH_KEY_SIZE, seed);\
+	signature11 = f_hash(&hash_offset_buffer11,		\
+		RTE_TABLE_HASH_KEY_SIZE, seed);			\
 	bucket11_index = signature11 & (f->n_buckets - 1);	\
 	bucket11 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket11_index * f->bucket_size];	\
@@ -764,13 +790,17 @@ rte_table_hash_entry_delete_key8_ext(
 	void *a20, *a21;					\
 	uint64_t pkt20_mask, pkt21_mask;			\
 	uint64_t *key20, *key21;				\
+	uint64_t hash_offset_buffer20;				\
+	uint64_t hash_offset_buffer21;				\
 	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_offset_buffer20 = *key20 & f->key_mask;		\
+	hash_offset_buffer21 = *key21 & f->key_mask;		\
 								\
-	lookup_key8_cmp(key20, bucket20, pos20);		\
-	lookup_key8_cmp(key21, bucket21, pos21);		\
+	lookup_key8_cmp((&hash_offset_buffer20), bucket20, pos20);\
+	lookup_key8_cmp((&hash_offset_buffer21), bucket21, pos21);\
 								\
 	pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
 	pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
@@ -793,13 +823,17 @@ rte_table_hash_entry_delete_key8_ext(
 	void *a20, *a21;					\
 	uint64_t pkt20_mask, pkt21_mask, bucket20_mask, bucket21_mask;\
 	uint64_t *key20, *key21;				\
+	uint64_t hash_offset_buffer20;				\
+	uint64_t hash_offset_buffer21;				\
 	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_offset_buffer20 = *key20 & f->key_mask;		\
+	hash_offset_buffer21 = *key21 & f->key_mask;		\
 								\
-	lookup_key8_cmp(key20, bucket20, pos20);		\
-	lookup_key8_cmp(key21, bucket21, pos21);		\
+	lookup_key8_cmp((&hash_offset_buffer20), bucket20, pos20);\
+	lookup_key8_cmp((&hash_offset_buffer21), bucket21, pos21);\
 								\
 	pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
 	pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 2/8] librte_table: add key_mask parameter to 16-byte key hash parameters
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 3/8] librte_table: add 16 byte hash table operations with computed lookup roy.fan.zhang
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch relates to ABI change proposed for librte_table. key_mask
parameter is added for 16-byte key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_table/rte_table_hash.h       |  6 ++++
 lib/librte_table/rte_table_hash_key16.c | 53 ++++++++++++++++++++++++++++-----
 2 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index ef65355..e2c60e1 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -263,6 +263,9 @@ struct rte_table_hash_key16_lru_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** LRU hash table operations for pre-computed key signature */
@@ -290,6 +293,9 @@ struct rte_table_hash_key16_ext_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** Extendible bucket operations for pre-computed key signature */
diff --git a/lib/librte_table/rte_table_hash_key16.c b/lib/librte_table/rte_table_hash_key16.c
index f6a3306..ffd3249 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -85,6 +85,7 @@ struct rte_table_hash {
 	uint32_t bucket_size;
 	uint32_t signature_offset;
 	uint32_t key_offset;
+	uint64_t key_mask[2];
 	rte_table_hash_op_hash f_hash;
 	uint64_t seed;
 
@@ -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;
 
@@ -384,6 +393,14 @@ 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;
 }
 
@@ -609,11 +626,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 +651,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 +681,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;				\
@@ -749,13 +775,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 +810,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;\
@@ -1115,3 +1153,4 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_lookup = rte_table_hash_lookup_key16_ext,
 	.f_stats = rte_table_hash_key16_stats_read,
 };
+
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 3/8] librte_table: add 16 byte hash table operations with computed lookup
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 2/8] librte_table: add key_mask parameter to 16-byte " roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 4/8] app/test: modify app/test_table_combined and app/test_table_tables roy.fan.zhang
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch is to adding hash table operations for key signature
computed on lookup ("do-sig") for LRU hash tables and Extendible buckets.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_table/rte_table_hash.h       |   8 +
 lib/librte_table/rte_table_hash_key16.c | 358 +++++++++++++++++++++++++++++++-
 2 files changed, 363 insertions(+), 3 deletions(-)

diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index e2c60e1..9d17516 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -271,6 +271,10 @@ struct rte_table_hash_key16_lru_params {
 /** LRU hash table operations for pre-computed key signature */
 extern struct rte_table_ops rte_table_hash_key16_lru_ops;
 
+/** LRU hash table operations for key signature computed on lookup
+    ("do-sig") */
+extern struct rte_table_ops rte_table_hash_key16_lru_dosig_ops;
+
 /** Extendible bucket hash table parameters */
 struct rte_table_hash_key16_ext_params {
 	/** Maximum number of entries (and keys) in the table */
@@ -301,6 +305,10 @@ struct rte_table_hash_key16_ext_params {
 /** Extendible bucket operations for pre-computed key signature */
 extern struct rte_table_ops rte_table_hash_key16_ext_ops;
 
+/** Extendible bucket hash table operations for key signature computed on
+    lookup ("do-sig") */
+extern struct rte_table_ops rte_table_hash_key16_ext_dosig_ops;
+
 /**
  * 32-byte key hash tables
  *
diff --git a/lib/librte_table/rte_table_hash_key16.c b/lib/librte_table/rte_table_hash_key16.c
index ffd3249..427b534 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -620,6 +620,27 @@ rte_table_hash_entry_delete_key16_ext(
 	rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
 }
 
+#define lookup1_stage1_dosig(mbuf1, bucket1, f)			\
+{								\
+	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);		\
+								\
+	bucket_index = signature & (f->n_buckets - 1);		\
+	bucket1 = (struct rte_bucket_4_16 *)			\
+		&f->memory[bucket_index * f->bucket_size];	\
+	rte_prefetch0(bucket1);					\
+	rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
+}
+
 #define lookup1_stage2_lru(pkt2_index, mbuf2, bucket2,		\
 		pkts_mask_out, entries, f)			\
 {								\
@@ -769,6 +790,36 @@ rte_table_hash_entry_delete_key16_ext(
 	rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
 }
 
+#define lookup2_stage1_dosig(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;	\
+								\
+	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 *)				\
+		&f->memory[bucket10_index * f->bucket_size];	\
+	rte_prefetch0(bucket10);				\
+	rte_prefetch0((void *)(((uintptr_t) bucket10) + RTE_CACHE_LINE_SIZE));\
+								\
+	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];	\
+	rte_prefetch0(bucket11);				\
+	rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
+}
+
 #define lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,\
 		bucket20, bucket21, pkts_mask_out, entries, f)	\
 {								\
@@ -878,7 +929,8 @@ rte_table_hash_lookup_key16_lru(
 		}
 
 		*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;
 	}
 
@@ -968,11 +1020,141 @@ 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() */
 
 static int
+rte_table_hash_lookup_key16_lru_dosig(
+	void *table,
+	struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	uint64_t *lookup_hit_mask,
+	void **entries)
+{
+	struct rte_table_hash *f = (struct rte_table_hash *) table;
+	struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
+	struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
+	uint32_t pkt00_index, pkt01_index, pkt10_index;
+	uint32_t pkt11_index, pkt20_index, 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 */
+	if (__builtin_popcountll(pkts_mask) < 5) {
+		for ( ; pkts_mask; ) {
+			struct rte_bucket_4_16 *bucket;
+			struct rte_mbuf *mbuf;
+			uint32_t pkt_index;
+
+			lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+			lookup1_stage1_dosig(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));
+		return 0;
+	}
+
+	/*
+	 * Pipeline fill
+	 *
+	 */
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline feed */
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/*
+	 * Pipeline run
+	 *
+	 */
+	for ( ; pkts_mask; ) {
+		/* Pipeline feed */
+		bucket20 = bucket10;
+		bucket21 = bucket11;
+		mbuf20 = mbuf10;
+		mbuf21 = mbuf11;
+		mbuf10 = mbuf00;
+		mbuf11 = mbuf01;
+		pkt20_index = pkt10_index;
+		pkt21_index = pkt11_index;
+		pkt10_index = pkt00_index;
+		pkt11_index = pkt01_index;
+
+		/* Pipeline stage 0 */
+		lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
+			mbuf00, mbuf01, pkts, pkts_mask);
+
+		/* Pipeline stage 1 */
+		lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+		/* Pipeline stage 2 */
+		lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+			bucket20, bucket21, pkts_mask_out, entries, f);
+	}
+
+	/*
+	 * Pipeline flush
+	 *
+	 */
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries, f);
+
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		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));
+	return 0;
+} /* rte_table_hash_lookup_key16_lru_dosig() */
+
+static int
 rte_table_hash_lookup_key16_ext(
 	void *table,
 	struct rte_mbuf **pkts,
@@ -1118,11 +1300,164 @@ 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_lookup_key16_ext_dosig(
+	void *table,
+	struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	uint64_t *lookup_hit_mask,
+	void **entries)
+{
+	struct rte_table_hash *f = (struct rte_table_hash *) table;
+	struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
+	struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
+	uint32_t pkt00_index, pkt01_index, pkt10_index;
+	uint32_t pkt11_index, pkt20_index, pkt21_index;
+	uint64_t pkts_mask_out = 0, buckets_mask = 0;
+	struct rte_bucket_4_16 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
+	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 */
+	if (__builtin_popcountll(pkts_mask) < 5) {
+		for ( ; pkts_mask; ) {
+			struct rte_bucket_4_16 *bucket;
+			struct rte_mbuf *mbuf;
+			uint32_t pkt_index;
+
+			lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+			lookup1_stage1_dosig(mbuf, bucket, f);
+			lookup1_stage2_ext(pkt_index, mbuf, bucket,
+				pkts_mask_out, entries, buckets_mask,
+				buckets, keys, f);
+		}
+
+		goto grind_next_buckets;
+	}
+
+	/*
+	 * Pipeline fill
+	 *
+	 */
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline feed */
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/*
+	 * Pipeline run
+	 *
+	 */
+	for ( ; pkts_mask; ) {
+		/* Pipeline feed */
+		bucket20 = bucket10;
+		bucket21 = bucket11;
+		mbuf20 = mbuf10;
+		mbuf21 = mbuf11;
+		mbuf10 = mbuf00;
+		mbuf11 = mbuf01;
+		pkt20_index = pkt10_index;
+		pkt21_index = pkt11_index;
+		pkt10_index = pkt00_index;
+		pkt11_index = pkt01_index;
+
+		/* Pipeline stage 0 */
+		lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
+			mbuf00, mbuf01, pkts, pkts_mask);
+
+		/* Pipeline stage 1 */
+		lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+		/* Pipeline stage 2 */
+		lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+			bucket20, bucket21, pkts_mask_out, entries,
+			buckets_mask, buckets, keys, f);
+	}
+
+	/*
+	 * Pipeline flush
+	 *
+	 */
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries,
+		buckets_mask, buckets, keys, f);
+
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries,
+		buckets_mask, buckets, keys, f);
+
+grind_next_buckets:
+	/* Grind next buckets */
+	for ( ; buckets_mask; ) {
+		uint64_t buckets_mask_next = 0;
+
+		for ( ; buckets_mask; ) {
+			uint64_t pkt_mask;
+			uint32_t pkt_index;
+
+			pkt_index = __builtin_ctzll(buckets_mask);
+			pkt_mask = 1LLU << pkt_index;
+			buckets_mask &= ~pkt_mask;
+
+			lookup_grinder(pkt_index, buckets, keys, pkts_mask_out,
+				entries, buckets_mask_next, f);
+		}
+
+		buckets_mask = buckets_mask_next;
+	}
+
+	*lookup_hit_mask = 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_dosig() */
+
+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;
@@ -1145,6 +1480,15 @@ struct rte_table_ops rte_table_hash_key16_lru_ops = {
 	.f_stats = rte_table_hash_key16_stats_read,
 };
 
+struct rte_table_ops rte_table_hash_key16_lru_dosig_ops = {
+	.f_create = rte_table_hash_create_key16_lru,
+	.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_lookup = rte_table_hash_lookup_key16_lru_dosig,
+	.f_stats = rte_table_hash_key16_stats_read,
+};
+
 struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_create = rte_table_hash_create_key16_ext,
 	.f_free = rte_table_hash_free_key16_ext,
@@ -1154,3 +1498,11 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_stats = rte_table_hash_key16_stats_read,
 };
 
+struct rte_table_ops rte_table_hash_key16_ext_dosig_ops = {
+	.f_create = rte_table_hash_create_key16_ext,
+	.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_lookup = rte_table_hash_lookup_key16_ext_dosig,
+	.f_stats = rte_table_hash_key16_stats_read,
+};
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 4/8] app/test: modify app/test_table_combined and app/test_table_tables
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
                   ` (2 preceding siblings ...)
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 3/8] librte_table: add 16 byte hash table operations with computed lookup roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 5/8] app/test-pipeline: modify pipeline test roy.fan.zhang
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

Tests have been updated to work on added key_mask parameter for 8-byte
key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 app/test/test_table_combined.c | 4 ++++
 app/test/test_table_tables.c   | 6 ++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
index dd09da5..359ac45 100644
--- a/app/test/test_table_combined.c
+++ b/app/test/test_table_combined.c
@@ -419,6 +419,7 @@ test_table_hash8lru(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key8lru[8];
@@ -477,6 +478,7 @@ test_table_hash16lru(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key16lru[16];
@@ -594,6 +596,7 @@ test_table_hash8ext(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key8ext[8];
@@ -660,6 +663,7 @@ test_table_hash16ext(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key16ext[16];
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
index 566964b..cc222f1 100644
--- a/app/test/test_table_tables.c
+++ b/app/test/test_table_tables.c
@@ -651,7 +651,8 @@ test_table_hash_lru_generic(struct rte_table_ops *ops)
 		.f_hash = pipeline_test_hash,
 		.seed = 0,
 		.signature_offset = 1,
-		.key_offset = 32
+		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	hash_params.n_entries = 0;
@@ -766,7 +767,8 @@ test_table_hash_ext_generic(struct rte_table_ops *ops)
 		.f_hash = pipeline_test_hash,
 		.seed = 0,
 		.signature_offset = 1,
-		.key_offset = 32
+		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	hash_params.n_entries = 0;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 5/8] app/test-pipeline: modify pipeline test
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
                   ` (3 preceding siblings ...)
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 4/8] app/test: modify app/test_table_combined and app/test_table_tables roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 6/8] example/ip_pipeline: add parse_hex_string for internal use roy.fan.zhang
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

Test-pipeline have been updated to work on added key_mask parameter for
8-byte key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 app/test-pipeline/pipeline_hash.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
index 548615f..dda0d4d 100644
--- a/app/test-pipeline/pipeline_hash.c
+++ b/app/test-pipeline/pipeline_hash.c
@@ -216,6 +216,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.n_entries_ext = 1 << 23,
 			.signature_offset = 0,
 			.key_offset = 32,
+			.key_mask = NULL,
 			.f_hash = test_hash,
 			.seed = 0,
 		};
@@ -240,6 +241,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.n_entries = 1 << 24,
 			.signature_offset = 0,
 			.key_offset = 32,
+			.key_mask = NULL,
 			.f_hash = test_hash,
 			.seed = 0,
 		};
@@ -267,6 +269,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.key_offset = 32,
 			.f_hash = test_hash,
 			.seed = 0,
+			.key_mask = NULL,
 		};
 
 		struct rte_pipeline_table_params table_params = {
@@ -291,6 +294,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.key_offset = 32,
 			.f_hash = test_hash,
 			.seed = 0,
+			.key_mask = NULL
 		};
 
 		struct rte_pipeline_table_params table_params = {
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 6/8] example/ip_pipeline: add parse_hex_string for internal use
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
                   ` (4 preceding siblings ...)
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 5/8] app/test-pipeline: modify pipeline test roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline roy.fan.zhang
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch adds parse_hex_string function to parse hex string to uint8_t
array.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/ip_pipeline/config_parse.c | 70 +++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/pipeline.h     |  4 +++
 2 files changed, 74 insertions(+)

diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index c9b78f9..d7ee707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -455,6 +455,76 @@ parse_pipeline_core(uint32_t *socket,
 	return 0;
 }
 
+static uint32_t
+get_hex_val(char c)
+{
+	switch (c) {
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+		return c - '0';
+	case 'A':
+	case 'B':
+	case 'C':
+	case 'D':
+	case 'E':
+	case 'F':
+		return c - 'A' + 10;
+	case 'a':
+	case 'b':
+	case 'c':
+	case 'd':
+	case 'e':
+	case 'f':
+		return c - 'a' + 10;
+	default:
+		return 0;
+	}
+}
+
+int
+parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
+{
+	char *c;
+	uint32_t len, i;
+
+	/* Check input parameters */
+	if ((src == NULL) ||
+		(dst == NULL) ||
+		(size == NULL) ||
+		(*size == 0))
+		return -1;
+
+	len = strlen(src);
+	if (((len & 3) != 0) ||
+		(len > (*size) * 2))
+		return -1;
+	*size = len / 2;
+
+	for (c = src; *c != 0; c++) {
+		if ((((*c) >= '0') && ((*c) <= '9')) ||
+			(((*c) >= 'A') && ((*c) <= 'F')) ||
+			(((*c) >= 'a') && ((*c) <= 'f')))
+			continue;
+
+		return -1;
+	}
+
+	/* Convert chars to bytes */
+	for (i = 0; i < *size; i++)
+		dst[i] = get_hex_val(src[2 * i]) * 16 +
+			get_hex_val(src[2 * i + 1]);
+
+	return 0;
+}
+
 static size_t
 skip_digits(const char *src)
 {
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index b9a56ea..4063594 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -84,4 +84,8 @@ pipeline_type_cmds_count(struct pipeline_type *ptype)
 	return n_cmds;
 }
 
+/* Parse hex string to uint8_t array */
+int
+parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
+
 #endif
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
                   ` (5 preceding siblings ...)
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 6/8] example/ip_pipeline: add parse_hex_string for internal use roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice roy.fan.zhang
  2015-09-28 20:07 ` [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key Dumitrescu, Cristian
  8 siblings, 0 replies; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch updates the flow_classification pipeline for added key_mask
parameter in 8/16-byte key hash parameters. The update provides user
optional key_mask configuration item applying to the packets.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 .../pipeline/pipeline_flow_classification_be.c     | 56 ++++++++++++++++++++--
 1 file changed, 52 insertions(+), 4 deletions(-)

diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
index 06a648d..e22f96f 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
@@ -37,6 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_table_hash.h>
 #include <rte_byteorder.h>
+#include <pipeline.h>
 
 #include "pipeline_flow_classification_be.h"
 #include "hash_func.h"
@@ -49,6 +50,7 @@ struct pipeline_flow_classification {
 	uint32_t key_offset;
 	uint32_t key_size;
 	uint32_t hash_offset;
+	uint8_t *key_mask;
 } __rte_cache_aligned;
 
 static void *
@@ -125,8 +127,12 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 	uint32_t key_offset_present = 0;
 	uint32_t key_size_present = 0;
 	uint32_t hash_offset_present = 0;
+	uint32_t key_mask_present = 0;
 
 	uint32_t i;
+	char *key_mask_str = NULL;
+
+	p->hash_offset = 0;
 
 	for (i = 0; i < params->n_args; i++) {
 		char *arg_name = params->args_name[i];
@@ -171,6 +177,20 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 			continue;
 		}
 
+		/* key_mask */
+		if (strcmp(arg_name, "key_mask") == 0) {
+			if (key_mask_present)
+				return -1;
+
+			key_mask_str = strdup(arg_value);
+			if (key_mask_str == NULL)
+				return -1;
+
+			key_mask_present = 1;
+
+			continue;
+		}
+
 		/* hash_offset */
 		if (strcmp(arg_name, "hash_offset") == 0) {
 			if (hash_offset_present)
@@ -189,10 +209,23 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 	/* Check that mandatory arguments are present */
 	if ((n_flows_present == 0) ||
 		(key_offset_present == 0) ||
-		(key_size_present == 0) ||
-		(hash_offset_present == 0))
+		(key_size_present == 0))
 		return -1;
 
+	if (key_mask_present) {
+		p->key_mask = rte_malloc(NULL, p->key_size, 0);
+		if (p->key_mask == NULL)
+			return -1;
+
+		if (parse_hex_string(key_mask_str, p->key_mask, &p->key_size)
+			!= 0) {
+			free(p->key_mask);
+			return -1;
+		}
+
+		free(key_mask_str);
+	}
+
 	return 0;
 }
 
@@ -297,6 +330,7 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 			.signature_offset = p_fc->hash_offset,
 			.key_offset = p_fc->key_offset,
 			.f_hash = hash_func[(p_fc->key_size / 8) - 1],
+			.key_mask = p_fc->key_mask,
 			.seed = 0,
 		};
 
@@ -307,6 +341,7 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 			.signature_offset = p_fc->hash_offset,
 			.key_offset = p_fc->key_offset,
 			.f_hash = hash_func[(p_fc->key_size / 8) - 1],
+			.key_mask = p_fc->key_mask,
 			.seed = 0,
 		};
 
@@ -336,12 +371,25 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 
 		switch (p_fc->key_size) {
 		case 8:
-			table_params.ops = &rte_table_hash_key8_lru_ops;
+			if (p_fc->hash_offset != 0) {
+				table_params.ops =
+					&rte_table_hash_key8_ext_ops;
+			} else {
+				table_params.ops =
+					&rte_table_hash_key8_ext_dosig_ops;
+			}
 			table_params.arg_create = &table_hash_key8_params;
 			break;
+			break;
 
 		case 16:
-			table_params.ops = &rte_table_hash_key16_ext_ops;
+			if (p_fc->hash_offset != 0) {
+				table_params.ops =
+					&rte_table_hash_key16_ext_ops;
+			} else {
+				table_params.ops =
+					&rte_table_hash_key16_ext_dosig_ops;
+			}
 			table_params.arg_create = &table_hash_key16_params;
 			break;
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
                   ` (6 preceding siblings ...)
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline roy.fan.zhang
@ 2015-09-25 22:33 ` roy.fan.zhang
  2015-10-12 14:24   ` Thomas Monjalon
  2015-09-28 20:07 ` [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key Dumitrescu, Cristian
  8 siblings, 1 reply; 32+ messages in thread
From: roy.fan.zhang @ 2015-09-25 22:33 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

The LIBABIVER number is incremented. The release notes is updated and
the deprecation announce is removed.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 3 ---
 doc/guides/rel_notes/release_2_2.rst | 5 ++++-
 lib/librte_table/Makefile            | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index fffad80..2b6954e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -63,9 +63,6 @@ Deprecation Notices
 * librte_table: New functions for table entry bulk add/delete will be added
   to the table operations structure.
 
-* librte_table hash: Key mask parameter will be added to the hash table
-  parameter structure for 8-byte key and 16-byte key extendible bucket and
-  LRU tables.
 
 * librte_pipeline: The prototype for the pipeline input port, output port
   and table action handlers will be updated:
diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 9a70dae..a62f641 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -95,6 +95,9 @@ ABI Changes
 
 * The LPM structure is changed. The deprecated field mem_location is removed.
 
+* Key mask parameter is added to the hash table parameter structure for
+  8-byte key and 16-byte key extendible bucket and LRU tables. The
+  deprecated field mem_location is removed.
 
 Shared Library Versions
 -----------------------
@@ -127,6 +130,6 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_reorder.so.1
      librte_ring.so.1
      librte_sched.so.1
-     librte_table.so.1
+     librte_table.so.2
      librte_timer.so.1
      librte_vhost.so.1
diff --git a/lib/librte_table/Makefile b/lib/librte_table/Makefile
index c5b3eaf..7f02af3 100644
--- a/lib/librte_table/Makefile
+++ b/lib/librte_table/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 
 EXPORT_MAP := rte_table_version.map
 
-LIBABIVER := 1
+LIBABIVER := 2
 
 #
 # all source are stored in SRCS-y
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key
  2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
                   ` (7 preceding siblings ...)
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice roy.fan.zhang
@ 2015-09-28 20:07 ` Dumitrescu, Cristian
  8 siblings, 0 replies; 32+ messages in thread
From: Dumitrescu, Cristian @ 2015-09-28 20:07 UTC (permalink / raw)
  To: Zhang, Roy Fan, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of
> roy.fan.zhang@intel.com
> Sent: Friday, September 25, 2015 11:33 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-
> byte key
> 
> From: Fan Zhang <roy.fan.zhang@intel.com>
> 
> This patchset links to ABI change announced for librte_table. Key_mask
> parameters has been added to the hash table parameter structure for
> 8-byte key and 16-byte key extendible bucket and LRU tables.
> 

Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice
  2015-09-25 22:33 ` [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice roy.fan.zhang
@ 2015-10-12 14:24   ` Thomas Monjalon
  2015-10-12 16:30     ` Mcnamara, John
  0 siblings, 1 reply; 32+ messages in thread
From: Thomas Monjalon @ 2015-10-12 14:24 UTC (permalink / raw)
  To: roy.fan.zhang; +Cc: dev

Hi and welcome,
(it seems to be your first patch on DPDK)

2015-09-25 23:33, roy.fan.zhang@intel.com:
> --- a/doc/guides/rel_notes/release_2_2.rst
> +++ b/doc/guides/rel_notes/release_2_2.rst
> @@ -95,6 +95,9 @@ ABI Changes
>  
>  * The LPM structure is changed. The deprecated field mem_location is removed.
>  
> +* Key mask parameter is added to the hash table parameter structure for
> +  8-byte key and 16-byte key extendible bucket and LRU tables. The
> +  deprecated field mem_location is removed.

It seems the last sentence is a wrong copy/paste.

If a v2 is needed, please squash the release notes changes with the API changes
(patches 1 and 2).

Thanks

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice
  2015-10-12 14:24   ` Thomas Monjalon
@ 2015-10-12 16:30     ` Mcnamara, John
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
  2015-10-19 13:31       ` [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice Thomas Monjalon
  0 siblings, 2 replies; 32+ messages in thread
From: Mcnamara, John @ 2015-10-12 16:30 UTC (permalink / raw)
  To: Thomas Monjalon, Zhang, Roy Fan; +Cc: dev

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Monday, October 12, 2015 3:24 PM
> To: Zhang, Roy Fan
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and
> deprecation notice
> 
> If a v2 is needed, please squash the release notes changes with the API
> changes (patches 1 and 2).

Hi Thomas,

Could you clarify this? In general shouldn't we keep all lib/drivers/examples/doc changes in separate patches in the patchset?

John

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key
  2015-10-12 16:30     ` Mcnamara, John
@ 2015-10-13 13:57       ` Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters Jasvinder Singh
                           ` (8 more replies)
  2015-10-19 13:31       ` [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice Thomas Monjalon
  1 sibling, 9 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>


This patchset links to ABI change announced for librte_table.
Key_mask parameters has been added to the hash table parameter
structure for 8-byte key and 16-byte key extendible bucket
and LRU tables.

v2:
*change in release note.

Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

Fan Zhang (8):
  librte_table: add key_mask parameter to 8-byte key hash parameters
  librte_table: add key_mask parameter to 16-byte key hash parameters
  librte_table: add 16 byte hash table operations with computed lookup
  app/test: modify app/test_table_combined and app/test_table_tables
  app/test-pipeline: modify pipeline test
  example/ip_pipeline: add parse_hex_string for internal use
  example/ip_pipeline/pipeline: update flow_classification pipeline
  librte_table: modify release notes and deprecation notice

 app/test-pipeline/pipeline_hash.c                  |   4 +
 app/test/test_table_combined.c                     |   4 +
 app/test/test_table_tables.c                       |   6 +-
 doc/guides/rel_notes/deprecation.rst               |   3 -
 doc/guides/rel_notes/release_2_2.rst               |   4 +-
 examples/ip_pipeline/config_parse.c                |  70 ++++
 examples/ip_pipeline/pipeline.h                    |   4 +
 .../pipeline/pipeline_flow_classification_be.c     |  56 ++-
 lib/librte_table/Makefile                          |   2 +-
 lib/librte_table/rte_table_hash.h                  |  20 +
 lib/librte_table/rte_table_hash_key16.c            | 411 ++++++++++++++++++++-
 lib/librte_table/rte_table_hash_key8.c             |  54 ++-
 12 files changed, 607 insertions(+), 31 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 2/8] librte_table: add key_mask parameter to 16-byte " Jasvinder Singh
                           ` (7 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch relates to ABI change proposed for librte_table. key_mask
parameter is added for 8-byte key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_table/rte_table_hash.h      |  6 ++++
 lib/librte_table/rte_table_hash_key8.c | 54 +++++++++++++++++++++++++++-------
 2 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index 9181942..ef65355 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -196,6 +196,9 @@ struct rte_table_hash_key8_lru_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** LRU hash table operations for pre-computed key signature */
@@ -226,6 +229,9 @@ struct rte_table_hash_key8_ext_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** Extendible bucket hash table operations for pre-computed key signature */
diff --git a/lib/librte_table/rte_table_hash_key8.c b/lib/librte_table/rte_table_hash_key8.c
index b351a49..ccb20cf 100644
--- a/lib/librte_table/rte_table_hash_key8.c
+++ b/lib/librte_table/rte_table_hash_key8.c
@@ -82,6 +82,7 @@ struct rte_table_hash {
 	uint32_t bucket_size;
 	uint32_t signature_offset;
 	uint32_t key_offset;
+	uint64_t key_mask;
 	rte_table_hash_op_hash f_hash;
 	uint64_t seed;
 
@@ -160,6 +161,11 @@ rte_table_hash_create_key8_lru(void *params, int socket_id, uint32_t entry_size)
 	f->f_hash = p->f_hash;
 	f->seed = p->seed;
 
+	if (p->key_mask != NULL)
+		f->key_mask = ((uint64_t *)p->key_mask)[0];
+	else
+		f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
+
 	for (i = 0; i < n_buckets; i++) {
 		struct rte_bucket_4_8 *bucket;
 
@@ -372,6 +378,11 @@ rte_table_hash_create_key8_ext(void *params, int socket_id, uint32_t entry_size)
 	f->stack = (uint32_t *)
 		&f->memory[(n_buckets + n_buckets_ext) * f->bucket_size];
 
+	if (p->key_mask != NULL)
+		f->key_mask = ((uint64_t *)p->key_mask)[0];
+	else
+		f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
+
 	for (i = 0; i < n_buckets_ext; i++)
 		f->stack[i] = i;
 
@@ -586,9 +597,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t *key;						\
 	uint64_t signature;					\
 	uint32_t bucket_index;					\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf1, f->key_offset);\
-	signature = f->f_hash(key, RTE_TABLE_HASH_KEY_SIZE, f->seed);\
+	hash_key_buffer = *key & f->key_mask;			\
+	signature = f->f_hash(&hash_key_buffer,			\
+		RTE_TABLE_HASH_KEY_SIZE, f->seed);		\
 	bucket_index = signature & (f->n_buckets - 1);		\
 	bucket1 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket_index * f->bucket_size];	\
@@ -602,10 +616,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask;					\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+	hash_key_buffer = key[0] & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket2, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket2, pos);	\
 								\
 	pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -624,10 +640,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask, bucket_mask;				\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+	hash_key_buffer = *key & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket2, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket2, pos);	\
 								\
 	pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -651,11 +669,13 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask, bucket_mask;				\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	bucket = buckets[pkt_index];				\
 	key = keys[pkt_index];					\
+	hash_key_buffer = (*key) & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket, pos);	\
 								\
 	pkt_mask = ((bucket->signature >> pos) & 1LLU) << pkt_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -736,6 +756,8 @@ rte_table_hash_entry_delete_key8_ext(
 #define lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f)\
 {								\
 	uint64_t *key10, *key11;				\
+	uint64_t hash_offset_buffer10;				\
+	uint64_t hash_offset_buffer11;				\
 	uint64_t signature10, signature11;			\
 	uint32_t bucket10_index, bucket11_index;		\
 	rte_table_hash_op_hash f_hash = f->f_hash;		\
@@ -744,14 +766,18 @@ rte_table_hash_entry_delete_key8_ext(
 								\
 	key10 = RTE_MBUF_METADATA_UINT64_PTR(mbuf10, key_offset);\
 	key11 = RTE_MBUF_METADATA_UINT64_PTR(mbuf11, key_offset);\
+	hash_offset_buffer10 = *key10 & f->key_mask;		\
+	hash_offset_buffer11 = *key11 & f->key_mask;		\
 								\
-	signature10 = f_hash(key10, RTE_TABLE_HASH_KEY_SIZE, seed);\
+	signature10 = f_hash(&hash_offset_buffer10,		\
+		RTE_TABLE_HASH_KEY_SIZE, seed);			\
 	bucket10_index = signature10 & (f->n_buckets - 1);	\
 	bucket10 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket10_index * f->bucket_size];	\
 	rte_prefetch0(bucket10);				\
 								\
-	signature11 = f_hash(key11, RTE_TABLE_HASH_KEY_SIZE, seed);\
+	signature11 = f_hash(&hash_offset_buffer11,		\
+		RTE_TABLE_HASH_KEY_SIZE, seed);			\
 	bucket11_index = signature11 & (f->n_buckets - 1);	\
 	bucket11 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket11_index * f->bucket_size];	\
@@ -764,13 +790,17 @@ rte_table_hash_entry_delete_key8_ext(
 	void *a20, *a21;					\
 	uint64_t pkt20_mask, pkt21_mask;			\
 	uint64_t *key20, *key21;				\
+	uint64_t hash_offset_buffer20;				\
+	uint64_t hash_offset_buffer21;				\
 	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_offset_buffer20 = *key20 & f->key_mask;		\
+	hash_offset_buffer21 = *key21 & f->key_mask;		\
 								\
-	lookup_key8_cmp(key20, bucket20, pos20);		\
-	lookup_key8_cmp(key21, bucket21, pos21);		\
+	lookup_key8_cmp((&hash_offset_buffer20), bucket20, pos20);\
+	lookup_key8_cmp((&hash_offset_buffer21), bucket21, pos21);\
 								\
 	pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
 	pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
@@ -793,13 +823,17 @@ rte_table_hash_entry_delete_key8_ext(
 	void *a20, *a21;					\
 	uint64_t pkt20_mask, pkt21_mask, bucket20_mask, bucket21_mask;\
 	uint64_t *key20, *key21;				\
+	uint64_t hash_offset_buffer20;				\
+	uint64_t hash_offset_buffer21;				\
 	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_offset_buffer20 = *key20 & f->key_mask;		\
+	hash_offset_buffer21 = *key21 & f->key_mask;		\
 								\
-	lookup_key8_cmp(key20, bucket20, pos20);		\
-	lookup_key8_cmp(key21, bucket21, pos21);		\
+	lookup_key8_cmp((&hash_offset_buffer20), bucket20, pos20);\
+	lookup_key8_cmp((&hash_offset_buffer21), bucket21, pos21);\
 								\
 	pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
 	pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 2/8] librte_table: add key_mask parameter to 16-byte key hash parameters
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 3/8] librte_table: add 16 byte hash table operations with computed lookup Jasvinder Singh
                           ` (6 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch relates to ABI change proposed for librte_table. key_mask
parameter is added for 16-byte key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_table/rte_table_hash.h       |  6 ++++
 lib/librte_table/rte_table_hash_key16.c | 53 ++++++++++++++++++++++++++++-----
 2 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index ef65355..e2c60e1 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -263,6 +263,9 @@ struct rte_table_hash_key16_lru_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** LRU hash table operations for pre-computed key signature */
@@ -290,6 +293,9 @@ struct rte_table_hash_key16_ext_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** Extendible bucket operations for pre-computed key signature */
diff --git a/lib/librte_table/rte_table_hash_key16.c b/lib/librte_table/rte_table_hash_key16.c
index f6a3306..ffd3249 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -85,6 +85,7 @@ struct rte_table_hash {
 	uint32_t bucket_size;
 	uint32_t signature_offset;
 	uint32_t key_offset;
+	uint64_t key_mask[2];
 	rte_table_hash_op_hash f_hash;
 	uint64_t seed;
 
@@ -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;
 
@@ -384,6 +393,14 @@ 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;
 }
 
@@ -609,11 +626,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 +651,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 +681,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;				\
@@ -749,13 +775,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 +810,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;\
@@ -1115,3 +1153,4 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_lookup = rte_table_hash_lookup_key16_ext,
 	.f_stats = rte_table_hash_key16_stats_read,
 };
+
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 3/8] librte_table: add 16 byte hash table operations with computed lookup
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 2/8] librte_table: add key_mask parameter to 16-byte " Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 4/8] app/test: modify app/test_table_combined and app/test_table_tables Jasvinder Singh
                           ` (5 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch is to adding hash table operations for key signature
computed on lookup ("do-sig") for LRU hash tables and Extendible buckets.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_table/rte_table_hash.h       |   8 +
 lib/librte_table/rte_table_hash_key16.c | 358 +++++++++++++++++++++++++++++++-
 2 files changed, 363 insertions(+), 3 deletions(-)

diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index e2c60e1..9d17516 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -271,6 +271,10 @@ struct rte_table_hash_key16_lru_params {
 /** LRU hash table operations for pre-computed key signature */
 extern struct rte_table_ops rte_table_hash_key16_lru_ops;
 
+/** LRU hash table operations for key signature computed on lookup
+    ("do-sig") */
+extern struct rte_table_ops rte_table_hash_key16_lru_dosig_ops;
+
 /** Extendible bucket hash table parameters */
 struct rte_table_hash_key16_ext_params {
 	/** Maximum number of entries (and keys) in the table */
@@ -301,6 +305,10 @@ struct rte_table_hash_key16_ext_params {
 /** Extendible bucket operations for pre-computed key signature */
 extern struct rte_table_ops rte_table_hash_key16_ext_ops;
 
+/** Extendible bucket hash table operations for key signature computed on
+    lookup ("do-sig") */
+extern struct rte_table_ops rte_table_hash_key16_ext_dosig_ops;
+
 /**
  * 32-byte key hash tables
  *
diff --git a/lib/librte_table/rte_table_hash_key16.c b/lib/librte_table/rte_table_hash_key16.c
index ffd3249..427b534 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -620,6 +620,27 @@ rte_table_hash_entry_delete_key16_ext(
 	rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
 }
 
+#define lookup1_stage1_dosig(mbuf1, bucket1, f)			\
+{								\
+	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);		\
+								\
+	bucket_index = signature & (f->n_buckets - 1);		\
+	bucket1 = (struct rte_bucket_4_16 *)			\
+		&f->memory[bucket_index * f->bucket_size];	\
+	rte_prefetch0(bucket1);					\
+	rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
+}
+
 #define lookup1_stage2_lru(pkt2_index, mbuf2, bucket2,		\
 		pkts_mask_out, entries, f)			\
 {								\
@@ -769,6 +790,36 @@ rte_table_hash_entry_delete_key16_ext(
 	rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
 }
 
+#define lookup2_stage1_dosig(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;	\
+								\
+	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 *)				\
+		&f->memory[bucket10_index * f->bucket_size];	\
+	rte_prefetch0(bucket10);				\
+	rte_prefetch0((void *)(((uintptr_t) bucket10) + RTE_CACHE_LINE_SIZE));\
+								\
+	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];	\
+	rte_prefetch0(bucket11);				\
+	rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
+}
+
 #define lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,\
 		bucket20, bucket21, pkts_mask_out, entries, f)	\
 {								\
@@ -878,7 +929,8 @@ rte_table_hash_lookup_key16_lru(
 		}
 
 		*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;
 	}
 
@@ -968,11 +1020,141 @@ 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() */
 
 static int
+rte_table_hash_lookup_key16_lru_dosig(
+	void *table,
+	struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	uint64_t *lookup_hit_mask,
+	void **entries)
+{
+	struct rte_table_hash *f = (struct rte_table_hash *) table;
+	struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
+	struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
+	uint32_t pkt00_index, pkt01_index, pkt10_index;
+	uint32_t pkt11_index, pkt20_index, 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 */
+	if (__builtin_popcountll(pkts_mask) < 5) {
+		for ( ; pkts_mask; ) {
+			struct rte_bucket_4_16 *bucket;
+			struct rte_mbuf *mbuf;
+			uint32_t pkt_index;
+
+			lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+			lookup1_stage1_dosig(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));
+		return 0;
+	}
+
+	/*
+	 * Pipeline fill
+	 *
+	 */
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline feed */
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/*
+	 * Pipeline run
+	 *
+	 */
+	for ( ; pkts_mask; ) {
+		/* Pipeline feed */
+		bucket20 = bucket10;
+		bucket21 = bucket11;
+		mbuf20 = mbuf10;
+		mbuf21 = mbuf11;
+		mbuf10 = mbuf00;
+		mbuf11 = mbuf01;
+		pkt20_index = pkt10_index;
+		pkt21_index = pkt11_index;
+		pkt10_index = pkt00_index;
+		pkt11_index = pkt01_index;
+
+		/* Pipeline stage 0 */
+		lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
+			mbuf00, mbuf01, pkts, pkts_mask);
+
+		/* Pipeline stage 1 */
+		lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+		/* Pipeline stage 2 */
+		lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+			bucket20, bucket21, pkts_mask_out, entries, f);
+	}
+
+	/*
+	 * Pipeline flush
+	 *
+	 */
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries, f);
+
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		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));
+	return 0;
+} /* rte_table_hash_lookup_key16_lru_dosig() */
+
+static int
 rte_table_hash_lookup_key16_ext(
 	void *table,
 	struct rte_mbuf **pkts,
@@ -1118,11 +1300,164 @@ 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_lookup_key16_ext_dosig(
+	void *table,
+	struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	uint64_t *lookup_hit_mask,
+	void **entries)
+{
+	struct rte_table_hash *f = (struct rte_table_hash *) table;
+	struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
+	struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
+	uint32_t pkt00_index, pkt01_index, pkt10_index;
+	uint32_t pkt11_index, pkt20_index, pkt21_index;
+	uint64_t pkts_mask_out = 0, buckets_mask = 0;
+	struct rte_bucket_4_16 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
+	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 */
+	if (__builtin_popcountll(pkts_mask) < 5) {
+		for ( ; pkts_mask; ) {
+			struct rte_bucket_4_16 *bucket;
+			struct rte_mbuf *mbuf;
+			uint32_t pkt_index;
+
+			lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+			lookup1_stage1_dosig(mbuf, bucket, f);
+			lookup1_stage2_ext(pkt_index, mbuf, bucket,
+				pkts_mask_out, entries, buckets_mask,
+				buckets, keys, f);
+		}
+
+		goto grind_next_buckets;
+	}
+
+	/*
+	 * Pipeline fill
+	 *
+	 */
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline feed */
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/*
+	 * Pipeline run
+	 *
+	 */
+	for ( ; pkts_mask; ) {
+		/* Pipeline feed */
+		bucket20 = bucket10;
+		bucket21 = bucket11;
+		mbuf20 = mbuf10;
+		mbuf21 = mbuf11;
+		mbuf10 = mbuf00;
+		mbuf11 = mbuf01;
+		pkt20_index = pkt10_index;
+		pkt21_index = pkt11_index;
+		pkt10_index = pkt00_index;
+		pkt11_index = pkt01_index;
+
+		/* Pipeline stage 0 */
+		lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
+			mbuf00, mbuf01, pkts, pkts_mask);
+
+		/* Pipeline stage 1 */
+		lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+		/* Pipeline stage 2 */
+		lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+			bucket20, bucket21, pkts_mask_out, entries,
+			buckets_mask, buckets, keys, f);
+	}
+
+	/*
+	 * Pipeline flush
+	 *
+	 */
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries,
+		buckets_mask, buckets, keys, f);
+
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries,
+		buckets_mask, buckets, keys, f);
+
+grind_next_buckets:
+	/* Grind next buckets */
+	for ( ; buckets_mask; ) {
+		uint64_t buckets_mask_next = 0;
+
+		for ( ; buckets_mask; ) {
+			uint64_t pkt_mask;
+			uint32_t pkt_index;
+
+			pkt_index = __builtin_ctzll(buckets_mask);
+			pkt_mask = 1LLU << pkt_index;
+			buckets_mask &= ~pkt_mask;
+
+			lookup_grinder(pkt_index, buckets, keys, pkts_mask_out,
+				entries, buckets_mask_next, f);
+		}
+
+		buckets_mask = buckets_mask_next;
+	}
+
+	*lookup_hit_mask = 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_dosig() */
+
+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;
@@ -1145,6 +1480,15 @@ struct rte_table_ops rte_table_hash_key16_lru_ops = {
 	.f_stats = rte_table_hash_key16_stats_read,
 };
 
+struct rte_table_ops rte_table_hash_key16_lru_dosig_ops = {
+	.f_create = rte_table_hash_create_key16_lru,
+	.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_lookup = rte_table_hash_lookup_key16_lru_dosig,
+	.f_stats = rte_table_hash_key16_stats_read,
+};
+
 struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_create = rte_table_hash_create_key16_ext,
 	.f_free = rte_table_hash_free_key16_ext,
@@ -1154,3 +1498,11 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_stats = rte_table_hash_key16_stats_read,
 };
 
+struct rte_table_ops rte_table_hash_key16_ext_dosig_ops = {
+	.f_create = rte_table_hash_create_key16_ext,
+	.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_lookup = rte_table_hash_lookup_key16_ext_dosig,
+	.f_stats = rte_table_hash_key16_stats_read,
+};
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 4/8] app/test: modify app/test_table_combined and app/test_table_tables
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
                           ` (2 preceding siblings ...)
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 3/8] librte_table: add 16 byte hash table operations with computed lookup Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 5/8] app/test-pipeline: modify pipeline test Jasvinder Singh
                           ` (4 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

Tests have been updated to work on added key_mask parameter for 8-byte
key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 app/test/test_table_combined.c | 4 ++++
 app/test/test_table_tables.c   | 6 ++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
index dd09da5..359ac45 100644
--- a/app/test/test_table_combined.c
+++ b/app/test/test_table_combined.c
@@ -419,6 +419,7 @@ test_table_hash8lru(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key8lru[8];
@@ -477,6 +478,7 @@ test_table_hash16lru(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key16lru[16];
@@ -594,6 +596,7 @@ test_table_hash8ext(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key8ext[8];
@@ -660,6 +663,7 @@ test_table_hash16ext(void)
 		.seed = 0,
 		.signature_offset = 0,
 		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	uint8_t key16ext[16];
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
index 566964b..cc222f1 100644
--- a/app/test/test_table_tables.c
+++ b/app/test/test_table_tables.c
@@ -651,7 +651,8 @@ test_table_hash_lru_generic(struct rte_table_ops *ops)
 		.f_hash = pipeline_test_hash,
 		.seed = 0,
 		.signature_offset = 1,
-		.key_offset = 32
+		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	hash_params.n_entries = 0;
@@ -766,7 +767,8 @@ test_table_hash_ext_generic(struct rte_table_ops *ops)
 		.f_hash = pipeline_test_hash,
 		.seed = 0,
 		.signature_offset = 1,
-		.key_offset = 32
+		.key_offset = 32,
+		.key_mask = NULL,
 	};
 
 	hash_params.n_entries = 0;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 5/8] app/test-pipeline: modify pipeline test
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
                           ` (3 preceding siblings ...)
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 4/8] app/test: modify app/test_table_combined and app/test_table_tables Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add parse_hex_string for internal use Jasvinder Singh
                           ` (3 subsequent siblings)
  8 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

Test-pipeline have been updated to work on added key_mask parameter for
8-byte key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 app/test-pipeline/pipeline_hash.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
index 548615f..dda0d4d 100644
--- a/app/test-pipeline/pipeline_hash.c
+++ b/app/test-pipeline/pipeline_hash.c
@@ -216,6 +216,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.n_entries_ext = 1 << 23,
 			.signature_offset = 0,
 			.key_offset = 32,
+			.key_mask = NULL,
 			.f_hash = test_hash,
 			.seed = 0,
 		};
@@ -240,6 +241,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.n_entries = 1 << 24,
 			.signature_offset = 0,
 			.key_offset = 32,
+			.key_mask = NULL,
 			.f_hash = test_hash,
 			.seed = 0,
 		};
@@ -267,6 +269,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.key_offset = 32,
 			.f_hash = test_hash,
 			.seed = 0,
+			.key_mask = NULL,
 		};
 
 		struct rte_pipeline_table_params table_params = {
@@ -291,6 +294,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.key_offset = 32,
 			.f_hash = test_hash,
 			.seed = 0,
+			.key_mask = NULL
 		};
 
 		struct rte_pipeline_table_params table_params = {
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add parse_hex_string for internal use
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
                           ` (4 preceding siblings ...)
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 5/8] app/test-pipeline: modify pipeline test Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-19 13:49           ` Thomas Monjalon
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline Jasvinder Singh
                           ` (2 subsequent siblings)
  8 siblings, 1 reply; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch adds parse_hex_string function to parse hex string to uint8_t
array.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/ip_pipeline/config_parse.c | 70 +++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/pipeline.h     |  4 +++
 2 files changed, 74 insertions(+)

diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index c9b78f9..d7ee707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -455,6 +455,76 @@ parse_pipeline_core(uint32_t *socket,
 	return 0;
 }
 
+static uint32_t
+get_hex_val(char c)
+{
+	switch (c) {
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+		return c - '0';
+	case 'A':
+	case 'B':
+	case 'C':
+	case 'D':
+	case 'E':
+	case 'F':
+		return c - 'A' + 10;
+	case 'a':
+	case 'b':
+	case 'c':
+	case 'd':
+	case 'e':
+	case 'f':
+		return c - 'a' + 10;
+	default:
+		return 0;
+	}
+}
+
+int
+parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
+{
+	char *c;
+	uint32_t len, i;
+
+	/* Check input parameters */
+	if ((src == NULL) ||
+		(dst == NULL) ||
+		(size == NULL) ||
+		(*size == 0))
+		return -1;
+
+	len = strlen(src);
+	if (((len & 3) != 0) ||
+		(len > (*size) * 2))
+		return -1;
+	*size = len / 2;
+
+	for (c = src; *c != 0; c++) {
+		if ((((*c) >= '0') && ((*c) <= '9')) ||
+			(((*c) >= 'A') && ((*c) <= 'F')) ||
+			(((*c) >= 'a') && ((*c) <= 'f')))
+			continue;
+
+		return -1;
+	}
+
+	/* Convert chars to bytes */
+	for (i = 0; i < *size; i++)
+		dst[i] = get_hex_val(src[2 * i]) * 16 +
+			get_hex_val(src[2 * i + 1]);
+
+	return 0;
+}
+
 static size_t
 skip_digits(const char *src)
 {
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index b9a56ea..4063594 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -84,4 +84,8 @@ pipeline_type_cmds_count(struct pipeline_type *ptype)
 	return n_cmds;
 }
 
+/* Parse hex string to uint8_t array */
+int
+parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
+
 #endif
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
                           ` (5 preceding siblings ...)
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add parse_hex_string for internal use Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-19 13:57           ` Thomas Monjalon
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 8/8] librte_table: modify release notes and deprecation notice Jasvinder Singh
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
  8 siblings, 1 reply; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch updates the flow_classification pipeline for added key_mask
parameter in 8/16-byte key hash parameters. The update provides user
optional key_mask configuration item applying to the packets.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 .../pipeline/pipeline_flow_classification_be.c     | 56 ++++++++++++++++++++--
 1 file changed, 52 insertions(+), 4 deletions(-)

diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
index 06a648d..e22f96f 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
@@ -37,6 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_table_hash.h>
 #include <rte_byteorder.h>
+#include <pipeline.h>
 
 #include "pipeline_flow_classification_be.h"
 #include "hash_func.h"
@@ -49,6 +50,7 @@ struct pipeline_flow_classification {
 	uint32_t key_offset;
 	uint32_t key_size;
 	uint32_t hash_offset;
+	uint8_t *key_mask;
 } __rte_cache_aligned;
 
 static void *
@@ -125,8 +127,12 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 	uint32_t key_offset_present = 0;
 	uint32_t key_size_present = 0;
 	uint32_t hash_offset_present = 0;
+	uint32_t key_mask_present = 0;
 
 	uint32_t i;
+	char *key_mask_str = NULL;
+
+	p->hash_offset = 0;
 
 	for (i = 0; i < params->n_args; i++) {
 		char *arg_name = params->args_name[i];
@@ -171,6 +177,20 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 			continue;
 		}
 
+		/* key_mask */
+		if (strcmp(arg_name, "key_mask") == 0) {
+			if (key_mask_present)
+				return -1;
+
+			key_mask_str = strdup(arg_value);
+			if (key_mask_str == NULL)
+				return -1;
+
+			key_mask_present = 1;
+
+			continue;
+		}
+
 		/* hash_offset */
 		if (strcmp(arg_name, "hash_offset") == 0) {
 			if (hash_offset_present)
@@ -189,10 +209,23 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 	/* Check that mandatory arguments are present */
 	if ((n_flows_present == 0) ||
 		(key_offset_present == 0) ||
-		(key_size_present == 0) ||
-		(hash_offset_present == 0))
+		(key_size_present == 0))
 		return -1;
 
+	if (key_mask_present) {
+		p->key_mask = rte_malloc(NULL, p->key_size, 0);
+		if (p->key_mask == NULL)
+			return -1;
+
+		if (parse_hex_string(key_mask_str, p->key_mask, &p->key_size)
+			!= 0) {
+			free(p->key_mask);
+			return -1;
+		}
+
+		free(key_mask_str);
+	}
+
 	return 0;
 }
 
@@ -297,6 +330,7 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 			.signature_offset = p_fc->hash_offset,
 			.key_offset = p_fc->key_offset,
 			.f_hash = hash_func[(p_fc->key_size / 8) - 1],
+			.key_mask = p_fc->key_mask,
 			.seed = 0,
 		};
 
@@ -307,6 +341,7 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 			.signature_offset = p_fc->hash_offset,
 			.key_offset = p_fc->key_offset,
 			.f_hash = hash_func[(p_fc->key_size / 8) - 1],
+			.key_mask = p_fc->key_mask,
 			.seed = 0,
 		};
 
@@ -336,12 +371,25 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 
 		switch (p_fc->key_size) {
 		case 8:
-			table_params.ops = &rte_table_hash_key8_lru_ops;
+			if (p_fc->hash_offset != 0) {
+				table_params.ops =
+					&rte_table_hash_key8_ext_ops;
+			} else {
+				table_params.ops =
+					&rte_table_hash_key8_ext_dosig_ops;
+			}
 			table_params.arg_create = &table_hash_key8_params;
 			break;
+			break;
 
 		case 16:
-			table_params.ops = &rte_table_hash_key16_ext_ops;
+			if (p_fc->hash_offset != 0) {
+				table_params.ops =
+					&rte_table_hash_key16_ext_ops;
+			} else {
+				table_params.ops =
+					&rte_table_hash_key16_ext_dosig_ops;
+			}
 			table_params.arg_create = &table_hash_key16_params;
 			break;
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v2 8/8] librte_table: modify release notes and deprecation notice
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
                           ` (6 preceding siblings ...)
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline Jasvinder Singh
@ 2015-10-13 13:57         ` Jasvinder Singh
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
  8 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-13 13:57 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

The LIBABIVER number is incremented. The release notes is
updated and the deprecation announce is removed.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 doc/guides/rel_notes/deprecation.rst | 3 ---
 doc/guides/rel_notes/release_2_2.rst | 4 +++-
 lib/librte_table/Makefile            | 2 +-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index fa55117..06e0078 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -56,9 +56,6 @@ Deprecation Notices
 * librte_table: New functions for table entry bulk add/delete will be added
   to the table operations structure.
 
-* librte_table hash: Key mask parameter will be added to the hash table
-  parameter structure for 8-byte key and 16-byte key extendible bucket and
-  LRU tables.
 
 * librte_pipeline: The prototype for the pipeline input port, output port
   and table action handlers will be updated:
diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 5687676..30197ec 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -98,6 +98,8 @@ ABI Changes
 
 * The LPM structure is changed. The deprecated field mem_location is removed.
 
+* Key mask parameter is added to the hash table parameter structure for
+  8-byte key and 16-byte key extendible bucket and LRU tables.
 
 Shared Library Versions
 -----------------------
@@ -130,6 +132,6 @@ The libraries prepended with a plus sign were incremented in this version.
      librte_reorder.so.1
      librte_ring.so.1
      librte_sched.so.1
-     librte_table.so.1
+     librte_table.so.2
      librte_timer.so.1
      librte_vhost.so.1
diff --git a/lib/librte_table/Makefile b/lib/librte_table/Makefile
index c5b3eaf..7f02af3 100644
--- a/lib/librte_table/Makefile
+++ b/lib/librte_table/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
 
 EXPORT_MAP := rte_table_version.map
 
-LIBABIVER := 1
+LIBABIVER := 2
 
 #
 # all source are stored in SRCS-y
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice
  2015-10-12 16:30     ` Mcnamara, John
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
@ 2015-10-19 13:31       ` Thomas Monjalon
  1 sibling, 0 replies; 32+ messages in thread
From: Thomas Monjalon @ 2015-10-19 13:31 UTC (permalink / raw)
  To: Mcnamara, John; +Cc: dev

2015-10-12 16:30, Mcnamara, John:
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > If a v2 is needed, please squash the release notes changes with the API
> > changes (patches 1 and 2).
> 
> Hi Thomas,
> 
> Could you clarify this? In general shouldn't we keep all lib/drivers/examples/doc changes in separate patches in the patchset?

Why should we?
When reviewing a patch, having the doc atomically updated with the code change
will help to understand it.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add parse_hex_string for internal use
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add parse_hex_string for internal use Jasvinder Singh
@ 2015-10-19 13:49           ` Thomas Monjalon
  2015-10-20 14:31             ` Dumitrescu, Cristian
  0 siblings, 1 reply; 32+ messages in thread
From: Thomas Monjalon @ 2015-10-19 13:49 UTC (permalink / raw)
  To: Jasvinder Singh; +Cc: dev

2015-10-13 14:57, Jasvinder Singh:
> From: Fan Zhang <roy.fan.zhang@intel.com>
> +static uint32_t
> +get_hex_val(char c)
> +{
> +	switch (c) {
> +	case '0':
> +	case '1':
> +	case '2':
> +	case '3':
> +	case '4':
> +	case '5':
> +	case '6':
> +	case '7':
> +	case '8':
> +	case '9':
> +		return c - '0';
> +	case 'A':
> +	case 'B':
> +	case 'C':
> +	case 'D':
> +	case 'E':
> +	case 'F':
> +		return c - 'A' + 10;
> +	case 'a':
> +	case 'b':
> +	case 'c':
> +	case 'd':
> +	case 'e':
> +	case 'f':
> +		return c - 'a' + 10;
> +	default:
> +		return 0;
> +	}
> +}
> +
> +int
> +parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
> +{
> +	char *c;
> +	uint32_t len, i;
> +
> +	/* Check input parameters */
> +	if ((src == NULL) ||
> +		(dst == NULL) ||
> +		(size == NULL) ||
> +		(*size == 0))
> +		return -1;
> +
> +	len = strlen(src);
> +	if (((len & 3) != 0) ||
> +		(len > (*size) * 2))
> +		return -1;
> +	*size = len / 2;
> +
> +	for (c = src; *c != 0; c++) {
> +		if ((((*c) >= '0') && ((*c) <= '9')) ||
> +			(((*c) >= 'A') && ((*c) <= 'F')) ||
> +			(((*c) >= 'a') && ((*c) <= 'f')))
> +			continue;
> +
> +		return -1;
> +	}
> +
> +	/* Convert chars to bytes */
> +	for (i = 0; i < *size; i++)
> +		dst[i] = get_hex_val(src[2 * i]) * 16 +
> +			get_hex_val(src[2 * i + 1]);
> +
> +	return 0;
> +}

Why not use strtol()?

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [dpdk-dev] [PATCH v2 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline Jasvinder Singh
@ 2015-10-19 13:57           ` Thomas Monjalon
  0 siblings, 0 replies; 32+ messages in thread
From: Thomas Monjalon @ 2015-10-19 13:57 UTC (permalink / raw)
  To: Jasvinder Singh, Fan Zhang; +Cc: dev

2015-10-13 14:57, Jasvinder Singh:
> From: Fan Zhang <roy.fan.zhang@intel.com>
> +				table_params.ops =
> +					&rte_table_hash_key16_ext_dosig_ops;
> +			}

It doesn't build with shared library.
pipeline_flow_classification_be.c:(.text+0xa84): undefined reference to `rte_table_hash_key16_ext_dosig_ops'

Some functions are missing in lib/librte_table/rte_table_version.map

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add parse_hex_string for internal use
  2015-10-19 13:49           ` Thomas Monjalon
@ 2015-10-20 14:31             ` Dumitrescu, Cristian
  0 siblings, 0 replies; 32+ messages in thread
From: Dumitrescu, Cristian @ 2015-10-20 14:31 UTC (permalink / raw)
  To: Thomas Monjalon, Singh, Jasvinder, Zhang, Roy Fan; +Cc: dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Monday, October 19, 2015 4:50 PM
> To: Singh, Jasvinder <jasvinder.singh@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add
> parse_hex_string for internal use
> 
> 2015-10-13 14:57, Jasvinder Singh:
> > From: Fan Zhang <roy.fan.zhang@intel.com>
> > +static uint32_t
> > +get_hex_val(char c)
> > +{
> > +	switch (c) {
> > +	case '0':
> > +	case '1':
> > +	case '2':
> > +	case '3':
> > +	case '4':
> > +	case '5':
> > +	case '6':
> > +	case '7':
> > +	case '8':
> > +	case '9':
> > +		return c - '0';
> > +	case 'A':
> > +	case 'B':
> > +	case 'C':
> > +	case 'D':
> > +	case 'E':
> > +	case 'F':
> > +		return c - 'A' + 10;
> > +	case 'a':
> > +	case 'b':
> > +	case 'c':
> > +	case 'd':
> > +	case 'e':
> > +	case 'f':
> > +		return c - 'a' + 10;
> > +	default:
> > +		return 0;
> > +	}
> > +}
> > +
> > +int
> > +parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
> > +{
> > +	char *c;
> > +	uint32_t len, i;
> > +
> > +	/* Check input parameters */
> > +	if ((src == NULL) ||
> > +		(dst == NULL) ||
> > +		(size == NULL) ||
> > +		(*size == 0))
> > +		return -1;
> > +
> > +	len = strlen(src);
> > +	if (((len & 3) != 0) ||
> > +		(len > (*size) * 2))
> > +		return -1;
> > +	*size = len / 2;
> > +
> > +	for (c = src; *c != 0; c++) {
> > +		if ((((*c) >= '0') && ((*c) <= '9')) ||
> > +			(((*c) >= 'A') && ((*c) <= 'F')) ||
> > +			(((*c) >= 'a') && ((*c) <= 'f')))
> > +			continue;
> > +
> > +		return -1;
> > +	}
> > +
> > +	/* Convert chars to bytes */
> > +	for (i = 0; i < *size; i++)
> > +		dst[i] = get_hex_val(src[2 * i]) * 16 +
> > +			get_hex_val(src[2 * i + 1]);
> > +
> > +	return 0;
> > +}
> 
> Why not use strtol()?

Strtol() was considered, but the code would have been more complicated (more corner case errors to handle) and less readable (more difficult to maintain), so our vote went for this simpler solution.

This function needs to convert an array of characters of up to 128 hex digits to the associated array of bytes, with output byte on position I representing the value of the i-th pair of input characters. For example, "010203" gets converted to array [1, 2, 3]. It only needs very simple math, which leads to the above code, which looks very readable.

Strtol() was not really intended for this. Strtol() is primarily intended to convert up to 8 characters to the associated value. Using strtol() would be possible to use (to convert each 2 characters to the byte) but we end up with a lot of error cases to handle, which leads to more complex code in our opinion.

Thanks,
Cristian

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure
  2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
                           ` (7 preceding siblings ...)
  2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 8/8] librte_table: modify release notes and deprecation notice Jasvinder Singh
@ 2015-10-21 12:18         ` Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 1/6] librte_table: add key_mask parameter to 8- and 16-bytes key hash parameters Jasvinder Singh
                             ` (5 more replies)
  8 siblings, 6 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-21 12:18 UTC (permalink / raw)
  To: dev

This patchset links to ABI change announced for librte_table.
The key_mask parameters has been added to the hash table
parameter structure for 8-byte key and 16-byte key extendible
bucket and LRU tables.

v2:
*updated release note

v3:
*merged release note with source code patch
*fixed build error: added missing symbol to
librte_table/rte_table_version.map

Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

Fan Zhang (6):
  librte_table: add 16 byte hash table operations with computed lookup
  app/test: modify app/test_table_combined and app/test_table_tables
  app/test-pipeline: modify pipeline test
  example/ip_pipeline: add parse_hex_string for internal use
  example/ip_pipeline/pipeline: update flow_classification pipeline
  librte_table: add key_mask parameter to 8- and 16-bytes key hash
    parameters

 app/test-pipeline/pipeline_hash.c                  |   4 +
 app/test/test_table_combined.c                     |   5 +-
 app/test/test_table_tables.c                       |   6 +-
 doc/guides/rel_notes/deprecation.rst               |   4 -
 doc/guides/rel_notes/release_2_2.rst               |   4 +
 examples/ip_pipeline/config_parse.c                |  70 ++++
 examples/ip_pipeline/pipeline.h                    |   4 +
 .../pipeline/pipeline_flow_classification_be.c     |  56 ++-
 lib/librte_table/rte_table_hash.h                  |  20 +
 lib/librte_table/rte_table_hash_key16.c            | 411 ++++++++++++++++++++-
 lib/librte_table/rte_table_hash_key8.c             |  54 ++-
 lib/librte_table/rte_table_version.map             |   7 +
 12 files changed, 614 insertions(+), 31 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v3 1/6] librte_table: add key_mask parameter to 8- and 16-bytes key hash parameters
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
@ 2015-10-21 12:18           ` Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 2/6] librte_table: add 16 byte hash table operations with computed lookup Jasvinder Singh
                             ` (4 subsequent siblings)
  5 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-21 12:18 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch relates to ABI change proposed for librte_table.
The key_mask parameter is added for 8-byte and 16-byte
key extendible bucket and LRU tables.The release notes
is updated and the deprecation notice is removed.


Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 doc/guides/rel_notes/deprecation.rst    |  4 ---
 doc/guides/rel_notes/release_2_2.rst    |  4 +++
 lib/librte_table/rte_table_hash.h       | 12 ++++++++
 lib/librte_table/rte_table_hash_key16.c | 52 ++++++++++++++++++++++++++-----
 lib/librte_table/rte_table_hash_key8.c  | 54 +++++++++++++++++++++++++++------
 lib/librte_table/rte_table_version.map  |  7 +++++
 6 files changed, 112 insertions(+), 21 deletions(-)

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 018a119..f8b8ca9 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -48,10 +48,6 @@ Deprecation Notices
 * librte_table: New functions for table entry bulk add/delete will be added
   to the table operations structure.
 
-* librte_table hash: Key mask parameter will be added to the hash table
-  parameter structure for 8-byte key and 16-byte key extendible bucket and
-  LRU tables.
-
 * librte_pipeline: The prototype for the pipeline input port, output port
   and table action handlers will be updated:
   the pipeline parameter will be added, the packets mask parameter will be
diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 4f75cff..deb36c7 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -117,6 +117,10 @@ ABI Changes
 * librte_port: Macros to access the packet meta-data stored within the packet
   buffer has been adjusted to cover the packet mbuf structure.
 
+* librte_table hash: The key mask parameter is added to the hash table
+  parameter structure for 8-byte key and 16-byte key extendible bucket
+  and LRU tables.
+
 
 Shared Library Versions
 -----------------------
diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index 9181942..e2c60e1 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -196,6 +196,9 @@ struct rte_table_hash_key8_lru_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** LRU hash table operations for pre-computed key signature */
@@ -226,6 +229,9 @@ struct rte_table_hash_key8_ext_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** Extendible bucket hash table operations for pre-computed key signature */
@@ -257,6 +263,9 @@ struct rte_table_hash_key16_lru_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** LRU hash table operations for pre-computed key signature */
@@ -284,6 +293,9 @@ struct rte_table_hash_key16_ext_params {
 
 	/** Byte offset within packet meta-data where the key is located */
 	uint32_t key_offset;
+
+	/** Bit-mask to be AND-ed to the key on lookup */
+	uint8_t *key_mask;
 };
 
 /** Extendible bucket operations for pre-computed key signature */
diff --git a/lib/librte_table/rte_table_hash_key16.c b/lib/librte_table/rte_table_hash_key16.c
index f6a3306..0d6cc55 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -85,6 +85,7 @@ struct rte_table_hash {
 	uint32_t bucket_size;
 	uint32_t signature_offset;
 	uint32_t key_offset;
+	uint64_t key_mask[2];
 	rte_table_hash_op_hash f_hash;
 	uint64_t seed;
 
@@ -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;
 
@@ -384,6 +393,14 @@ 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;
 }
 
@@ -609,11 +626,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 +651,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 +681,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;				\
@@ -749,13 +775,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 +810,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;\
diff --git a/lib/librte_table/rte_table_hash_key8.c b/lib/librte_table/rte_table_hash_key8.c
index b351a49..ccb20cf 100644
--- a/lib/librte_table/rte_table_hash_key8.c
+++ b/lib/librte_table/rte_table_hash_key8.c
@@ -82,6 +82,7 @@ struct rte_table_hash {
 	uint32_t bucket_size;
 	uint32_t signature_offset;
 	uint32_t key_offset;
+	uint64_t key_mask;
 	rte_table_hash_op_hash f_hash;
 	uint64_t seed;
 
@@ -160,6 +161,11 @@ rte_table_hash_create_key8_lru(void *params, int socket_id, uint32_t entry_size)
 	f->f_hash = p->f_hash;
 	f->seed = p->seed;
 
+	if (p->key_mask != NULL)
+		f->key_mask = ((uint64_t *)p->key_mask)[0];
+	else
+		f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
+
 	for (i = 0; i < n_buckets; i++) {
 		struct rte_bucket_4_8 *bucket;
 
@@ -372,6 +378,11 @@ rte_table_hash_create_key8_ext(void *params, int socket_id, uint32_t entry_size)
 	f->stack = (uint32_t *)
 		&f->memory[(n_buckets + n_buckets_ext) * f->bucket_size];
 
+	if (p->key_mask != NULL)
+		f->key_mask = ((uint64_t *)p->key_mask)[0];
+	else
+		f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
+
 	for (i = 0; i < n_buckets_ext; i++)
 		f->stack[i] = i;
 
@@ -586,9 +597,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t *key;						\
 	uint64_t signature;					\
 	uint32_t bucket_index;					\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf1, f->key_offset);\
-	signature = f->f_hash(key, RTE_TABLE_HASH_KEY_SIZE, f->seed);\
+	hash_key_buffer = *key & f->key_mask;			\
+	signature = f->f_hash(&hash_key_buffer,			\
+		RTE_TABLE_HASH_KEY_SIZE, f->seed);		\
 	bucket_index = signature & (f->n_buckets - 1);		\
 	bucket1 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket_index * f->bucket_size];	\
@@ -602,10 +616,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask;					\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+	hash_key_buffer = key[0] & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket2, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket2, pos);	\
 								\
 	pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -624,10 +640,12 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask, bucket_mask;				\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
+	hash_key_buffer = *key & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket2, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket2, pos);	\
 								\
 	pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -651,11 +669,13 @@ rte_table_hash_entry_delete_key8_ext(
 	uint64_t pkt_mask, bucket_mask;				\
 	uint64_t *key;						\
 	uint32_t pos;						\
+	uint64_t hash_key_buffer;				\
 								\
 	bucket = buckets[pkt_index];				\
 	key = keys[pkt_index];					\
+	hash_key_buffer = (*key) & f->key_mask;			\
 								\
-	lookup_key8_cmp(key, bucket, pos);			\
+	lookup_key8_cmp((&hash_key_buffer), bucket, pos);	\
 								\
 	pkt_mask = ((bucket->signature >> pos) & 1LLU) << pkt_index;\
 	pkts_mask_out |= pkt_mask;				\
@@ -736,6 +756,8 @@ rte_table_hash_entry_delete_key8_ext(
 #define lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f)\
 {								\
 	uint64_t *key10, *key11;				\
+	uint64_t hash_offset_buffer10;				\
+	uint64_t hash_offset_buffer11;				\
 	uint64_t signature10, signature11;			\
 	uint32_t bucket10_index, bucket11_index;		\
 	rte_table_hash_op_hash f_hash = f->f_hash;		\
@@ -744,14 +766,18 @@ rte_table_hash_entry_delete_key8_ext(
 								\
 	key10 = RTE_MBUF_METADATA_UINT64_PTR(mbuf10, key_offset);\
 	key11 = RTE_MBUF_METADATA_UINT64_PTR(mbuf11, key_offset);\
+	hash_offset_buffer10 = *key10 & f->key_mask;		\
+	hash_offset_buffer11 = *key11 & f->key_mask;		\
 								\
-	signature10 = f_hash(key10, RTE_TABLE_HASH_KEY_SIZE, seed);\
+	signature10 = f_hash(&hash_offset_buffer10,		\
+		RTE_TABLE_HASH_KEY_SIZE, seed);			\
 	bucket10_index = signature10 & (f->n_buckets - 1);	\
 	bucket10 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket10_index * f->bucket_size];	\
 	rte_prefetch0(bucket10);				\
 								\
-	signature11 = f_hash(key11, RTE_TABLE_HASH_KEY_SIZE, seed);\
+	signature11 = f_hash(&hash_offset_buffer11,		\
+		RTE_TABLE_HASH_KEY_SIZE, seed);			\
 	bucket11_index = signature11 & (f->n_buckets - 1);	\
 	bucket11 = (struct rte_bucket_4_8 *)			\
 		&f->memory[bucket11_index * f->bucket_size];	\
@@ -764,13 +790,17 @@ rte_table_hash_entry_delete_key8_ext(
 	void *a20, *a21;					\
 	uint64_t pkt20_mask, pkt21_mask;			\
 	uint64_t *key20, *key21;				\
+	uint64_t hash_offset_buffer20;				\
+	uint64_t hash_offset_buffer21;				\
 	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_offset_buffer20 = *key20 & f->key_mask;		\
+	hash_offset_buffer21 = *key21 & f->key_mask;		\
 								\
-	lookup_key8_cmp(key20, bucket20, pos20);		\
-	lookup_key8_cmp(key21, bucket21, pos21);		\
+	lookup_key8_cmp((&hash_offset_buffer20), bucket20, pos20);\
+	lookup_key8_cmp((&hash_offset_buffer21), bucket21, pos21);\
 								\
 	pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
 	pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
@@ -793,13 +823,17 @@ rte_table_hash_entry_delete_key8_ext(
 	void *a20, *a21;					\
 	uint64_t pkt20_mask, pkt21_mask, bucket20_mask, bucket21_mask;\
 	uint64_t *key20, *key21;				\
+	uint64_t hash_offset_buffer20;				\
+	uint64_t hash_offset_buffer21;				\
 	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_offset_buffer20 = *key20 & f->key_mask;		\
+	hash_offset_buffer21 = *key21 & f->key_mask;		\
 								\
-	lookup_key8_cmp(key20, bucket20, pos20);		\
-	lookup_key8_cmp(key21, bucket21, pos21);		\
+	lookup_key8_cmp((&hash_offset_buffer20), bucket20, pos20);\
+	lookup_key8_cmp((&hash_offset_buffer21), bucket21, pos21);\
 								\
 	pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
 	pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
diff --git a/lib/librte_table/rte_table_version.map b/lib/librte_table/rte_table_version.map
index d33f926..f767a50 100644
--- a/lib/librte_table/rte_table_version.map
+++ b/lib/librte_table/rte_table_version.map
@@ -19,3 +19,10 @@ DPDK_2.0 {
 
 	local: *;
 };
+
+DPDK_2.2 {
+	global:
+
+	rte_table_hash_key16_ext_dosig_ops;
+
+} DPDK_2.0;
\ No newline at end of file
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v3 2/6] librte_table: add 16 byte hash table operations with computed lookup
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 1/6] librte_table: add key_mask parameter to 8- and 16-bytes key hash parameters Jasvinder Singh
@ 2015-10-21 12:18           ` Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 3/6] app/test: modify app/test_table_combined and app/test_table_tables Jasvinder Singh
                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-21 12:18 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch is to adding hash table operations for key signature
computed on lookup ("do-sig") for LRU hash tables and Extendible buckets.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_table/rte_table_hash.h       |   8 +
 lib/librte_table/rte_table_hash_key16.c | 359 +++++++++++++++++++++++++++++++-
 2 files changed, 364 insertions(+), 3 deletions(-)

diff --git a/lib/librte_table/rte_table_hash.h b/lib/librte_table/rte_table_hash.h
index e2c60e1..9d17516 100644
--- a/lib/librte_table/rte_table_hash.h
+++ b/lib/librte_table/rte_table_hash.h
@@ -271,6 +271,10 @@ struct rte_table_hash_key16_lru_params {
 /** LRU hash table operations for pre-computed key signature */
 extern struct rte_table_ops rte_table_hash_key16_lru_ops;
 
+/** LRU hash table operations for key signature computed on lookup
+    ("do-sig") */
+extern struct rte_table_ops rte_table_hash_key16_lru_dosig_ops;
+
 /** Extendible bucket hash table parameters */
 struct rte_table_hash_key16_ext_params {
 	/** Maximum number of entries (and keys) in the table */
@@ -301,6 +305,10 @@ struct rte_table_hash_key16_ext_params {
 /** Extendible bucket operations for pre-computed key signature */
 extern struct rte_table_ops rte_table_hash_key16_ext_ops;
 
+/** Extendible bucket hash table operations for key signature computed on
+    lookup ("do-sig") */
+extern struct rte_table_ops rte_table_hash_key16_ext_dosig_ops;
+
 /**
  * 32-byte key hash tables
  *
diff --git a/lib/librte_table/rte_table_hash_key16.c b/lib/librte_table/rte_table_hash_key16.c
index 0d6cc55..427b534 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -620,6 +620,27 @@ rte_table_hash_entry_delete_key16_ext(
 	rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
 }
 
+#define lookup1_stage1_dosig(mbuf1, bucket1, f)			\
+{								\
+	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);		\
+								\
+	bucket_index = signature & (f->n_buckets - 1);		\
+	bucket1 = (struct rte_bucket_4_16 *)			\
+		&f->memory[bucket_index * f->bucket_size];	\
+	rte_prefetch0(bucket1);					\
+	rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
+}
+
 #define lookup1_stage2_lru(pkt2_index, mbuf2, bucket2,		\
 		pkts_mask_out, entries, f)			\
 {								\
@@ -769,6 +790,36 @@ rte_table_hash_entry_delete_key16_ext(
 	rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
 }
 
+#define lookup2_stage1_dosig(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;	\
+								\
+	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 *)				\
+		&f->memory[bucket10_index * f->bucket_size];	\
+	rte_prefetch0(bucket10);				\
+	rte_prefetch0((void *)(((uintptr_t) bucket10) + RTE_CACHE_LINE_SIZE));\
+								\
+	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];	\
+	rte_prefetch0(bucket11);				\
+	rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
+}
+
 #define lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,\
 		bucket20, bucket21, pkts_mask_out, entries, f)	\
 {								\
@@ -878,7 +929,8 @@ rte_table_hash_lookup_key16_lru(
 		}
 
 		*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;
 	}
 
@@ -968,11 +1020,141 @@ 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() */
 
 static int
+rte_table_hash_lookup_key16_lru_dosig(
+	void *table,
+	struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	uint64_t *lookup_hit_mask,
+	void **entries)
+{
+	struct rte_table_hash *f = (struct rte_table_hash *) table;
+	struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
+	struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
+	uint32_t pkt00_index, pkt01_index, pkt10_index;
+	uint32_t pkt11_index, pkt20_index, 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 */
+	if (__builtin_popcountll(pkts_mask) < 5) {
+		for ( ; pkts_mask; ) {
+			struct rte_bucket_4_16 *bucket;
+			struct rte_mbuf *mbuf;
+			uint32_t pkt_index;
+
+			lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+			lookup1_stage1_dosig(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));
+		return 0;
+	}
+
+	/*
+	 * Pipeline fill
+	 *
+	 */
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline feed */
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/*
+	 * Pipeline run
+	 *
+	 */
+	for ( ; pkts_mask; ) {
+		/* Pipeline feed */
+		bucket20 = bucket10;
+		bucket21 = bucket11;
+		mbuf20 = mbuf10;
+		mbuf21 = mbuf11;
+		mbuf10 = mbuf00;
+		mbuf11 = mbuf01;
+		pkt20_index = pkt10_index;
+		pkt21_index = pkt11_index;
+		pkt10_index = pkt00_index;
+		pkt11_index = pkt01_index;
+
+		/* Pipeline stage 0 */
+		lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
+			mbuf00, mbuf01, pkts, pkts_mask);
+
+		/* Pipeline stage 1 */
+		lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+		/* Pipeline stage 2 */
+		lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+			bucket20, bucket21, pkts_mask_out, entries, f);
+	}
+
+	/*
+	 * Pipeline flush
+	 *
+	 */
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries, f);
+
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		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));
+	return 0;
+} /* rte_table_hash_lookup_key16_lru_dosig() */
+
+static int
 rte_table_hash_lookup_key16_ext(
 	void *table,
 	struct rte_mbuf **pkts,
@@ -1118,11 +1300,164 @@ 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_lookup_key16_ext_dosig(
+	void *table,
+	struct rte_mbuf **pkts,
+	uint64_t pkts_mask,
+	uint64_t *lookup_hit_mask,
+	void **entries)
+{
+	struct rte_table_hash *f = (struct rte_table_hash *) table;
+	struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
+	struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
+	uint32_t pkt00_index, pkt01_index, pkt10_index;
+	uint32_t pkt11_index, pkt20_index, pkt21_index;
+	uint64_t pkts_mask_out = 0, buckets_mask = 0;
+	struct rte_bucket_4_16 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
+	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 */
+	if (__builtin_popcountll(pkts_mask) < 5) {
+		for ( ; pkts_mask; ) {
+			struct rte_bucket_4_16 *bucket;
+			struct rte_mbuf *mbuf;
+			uint32_t pkt_index;
+
+			lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask);
+			lookup1_stage1_dosig(mbuf, bucket, f);
+			lookup1_stage2_ext(pkt_index, mbuf, bucket,
+				pkts_mask_out, entries, buckets_mask,
+				buckets, keys, f);
+		}
+
+		goto grind_next_buckets;
+	}
+
+	/*
+	 * Pipeline fill
+	 *
+	 */
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline feed */
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 0 */
+	lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
+		pkts_mask);
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/*
+	 * Pipeline run
+	 *
+	 */
+	for ( ; pkts_mask; ) {
+		/* Pipeline feed */
+		bucket20 = bucket10;
+		bucket21 = bucket11;
+		mbuf20 = mbuf10;
+		mbuf21 = mbuf11;
+		mbuf10 = mbuf00;
+		mbuf11 = mbuf01;
+		pkt20_index = pkt10_index;
+		pkt21_index = pkt11_index;
+		pkt10_index = pkt00_index;
+		pkt11_index = pkt01_index;
+
+		/* Pipeline stage 0 */
+		lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
+			mbuf00, mbuf01, pkts, pkts_mask);
+
+		/* Pipeline stage 1 */
+		lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+		/* Pipeline stage 2 */
+		lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+			bucket20, bucket21, pkts_mask_out, entries,
+			buckets_mask, buckets, keys, f);
+	}
+
+	/*
+	 * Pipeline flush
+	 *
+	 */
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	mbuf10 = mbuf00;
+	mbuf11 = mbuf01;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+	pkt10_index = pkt00_index;
+	pkt11_index = pkt01_index;
+
+	/* Pipeline stage 1 */
+	lookup2_stage1_dosig(mbuf10, mbuf11, bucket10, bucket11, f);
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries,
+		buckets_mask, buckets, keys, f);
+
+	/* Pipeline feed */
+	bucket20 = bucket10;
+	bucket21 = bucket11;
+	mbuf20 = mbuf10;
+	mbuf21 = mbuf11;
+	pkt20_index = pkt10_index;
+	pkt21_index = pkt11_index;
+
+	/* Pipeline stage 2 */
+	lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
+		bucket20, bucket21, pkts_mask_out, entries,
+		buckets_mask, buckets, keys, f);
+
+grind_next_buckets:
+	/* Grind next buckets */
+	for ( ; buckets_mask; ) {
+		uint64_t buckets_mask_next = 0;
+
+		for ( ; buckets_mask; ) {
+			uint64_t pkt_mask;
+			uint32_t pkt_index;
+
+			pkt_index = __builtin_ctzll(buckets_mask);
+			pkt_mask = 1LLU << pkt_index;
+			buckets_mask &= ~pkt_mask;
+
+			lookup_grinder(pkt_index, buckets, keys, pkts_mask_out,
+				entries, buckets_mask_next, f);
+		}
+
+		buckets_mask = buckets_mask_next;
+	}
+
+	*lookup_hit_mask = 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_dosig() */
+
+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;
@@ -1145,6 +1480,15 @@ struct rte_table_ops rte_table_hash_key16_lru_ops = {
 	.f_stats = rte_table_hash_key16_stats_read,
 };
 
+struct rte_table_ops rte_table_hash_key16_lru_dosig_ops = {
+	.f_create = rte_table_hash_create_key16_lru,
+	.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_lookup = rte_table_hash_lookup_key16_lru_dosig,
+	.f_stats = rte_table_hash_key16_stats_read,
+};
+
 struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_create = rte_table_hash_create_key16_ext,
 	.f_free = rte_table_hash_free_key16_ext,
@@ -1153,3 +1497,12 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
 	.f_lookup = rte_table_hash_lookup_key16_ext,
 	.f_stats = rte_table_hash_key16_stats_read,
 };
+
+struct rte_table_ops rte_table_hash_key16_ext_dosig_ops = {
+	.f_create = rte_table_hash_create_key16_ext,
+	.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_lookup = rte_table_hash_lookup_key16_ext_dosig,
+	.f_stats = rte_table_hash_key16_stats_read,
+};
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v3 3/6] app/test: modify app/test_table_combined and app/test_table_tables
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 1/6] librte_table: add key_mask parameter to 8- and 16-bytes key hash parameters Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 2/6] librte_table: add 16 byte hash table operations with computed lookup Jasvinder Singh
@ 2015-10-21 12:18           ` Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 4/6] app/test-pipeline: modify pipeline test Jasvinder Singh
                             ` (2 subsequent siblings)
  5 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-21 12:18 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

Tests have been updated to work on added key_mask parameter for 8-byte
key extendible bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 app/test/test_table_combined.c | 5 ++++-
 app/test/test_table_tables.c   | 6 ++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
index 18daeec..8bf4aeb 100644
--- a/app/test/test_table_combined.c
+++ b/app/test/test_table_combined.c
@@ -418,9 +418,9 @@ test_table_hash8lru(void)
 	struct rte_table_hash_key8_lru_params key8lru_params = {
 		.n_entries = 1<<24,
 		.f_hash = pipeline_test_hash,
-		.seed = 0,
 		.signature_offset = APP_METADATA_OFFSET(0),
 		.key_offset = APP_METADATA_OFFSET(32),
+		.key_mask = NULL,
 	};
 
 	uint8_t key8lru[8];
@@ -479,6 +479,7 @@ test_table_hash16lru(void)
 		.seed = 0,
 		.signature_offset = APP_METADATA_OFFSET(0),
 		.key_offset = APP_METADATA_OFFSET(32),
+		.key_mask = NULL,
 	};
 
 	uint8_t key16lru[16];
@@ -596,6 +597,7 @@ test_table_hash8ext(void)
 		.seed = 0,
 		.signature_offset = APP_METADATA_OFFSET(0),
 		.key_offset = APP_METADATA_OFFSET(32),
+		.key_mask = NULL,
 	};
 
 	uint8_t key8ext[8];
@@ -662,6 +664,7 @@ test_table_hash16ext(void)
 		.seed = 0,
 		.signature_offset = APP_METADATA_OFFSET(0),
 		.key_offset = APP_METADATA_OFFSET(32),
+		.key_mask = NULL,
 	};
 
 	uint8_t key16ext[16];
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
index cf7c62d..b6364c4 100644
--- a/app/test/test_table_tables.c
+++ b/app/test/test_table_tables.c
@@ -669,7 +669,8 @@ test_table_hash_lru_generic(struct rte_table_ops *ops)
 		.f_hash = pipeline_test_hash,
 		.seed = 0,
 		.signature_offset = APP_METADATA_OFFSET(1),
-		.key_offset = APP_METADATA_OFFSET(32)
+		.key_offset = APP_METADATA_OFFSET(32),
+		.key_mask = NULL,
 	};
 
 	hash_params.n_entries = 0;
@@ -784,7 +785,8 @@ test_table_hash_ext_generic(struct rte_table_ops *ops)
 		.f_hash = pipeline_test_hash,
 		.seed = 0,
 		.signature_offset = APP_METADATA_OFFSET(1),
-		.key_offset = APP_METADATA_OFFSET(32)
+		.key_offset = APP_METADATA_OFFSET(32),
+		.key_mask = NULL,
 	};
 
 	hash_params.n_entries = 0;
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v3 4/6] app/test-pipeline: modify pipeline test
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
                             ` (2 preceding siblings ...)
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 3/6] app/test: modify app/test_table_combined and app/test_table_tables Jasvinder Singh
@ 2015-10-21 12:18           ` Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 5/6] example/ip_pipeline: add parse_hex_string for internal use Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 6/6] example/ip_pipeline/pipeline: update flow_classification pipeline Jasvinder Singh
  5 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-21 12:18 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

Test-pipeline has been updated to work on added
key_mask parameter for 8-byte key extendible
bucket and LRU tables.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 app/test-pipeline/pipeline_hash.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
index 5e4e17f..8b888d7 100644
--- a/app/test-pipeline/pipeline_hash.c
+++ b/app/test-pipeline/pipeline_hash.c
@@ -216,6 +216,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.n_entries_ext = 1 << 23,
 			.signature_offset = APP_METADATA_OFFSET(0),
 			.key_offset = APP_METADATA_OFFSET(32),
+			.key_mask = NULL,
 			.f_hash = test_hash,
 			.seed = 0,
 		};
@@ -240,6 +241,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.n_entries = 1 << 24,
 			.signature_offset = APP_METADATA_OFFSET(0),
 			.key_offset = APP_METADATA_OFFSET(32),
+			.key_mask = NULL,
 			.f_hash = test_hash,
 			.seed = 0,
 		};
@@ -267,6 +269,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.key_offset = APP_METADATA_OFFSET(32),
 			.f_hash = test_hash,
 			.seed = 0,
+			.key_mask = NULL,
 		};
 
 		struct rte_pipeline_table_params table_params = {
@@ -291,6 +294,7 @@ app_main_loop_worker_pipeline_hash(void) {
 			.key_offset = APP_METADATA_OFFSET(32),
 			.f_hash = test_hash,
 			.seed = 0,
+			.key_mask = NULL,
 		};
 
 		struct rte_pipeline_table_params table_params = {
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v3 5/6] example/ip_pipeline: add parse_hex_string for internal use
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
                             ` (3 preceding siblings ...)
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 4/6] app/test-pipeline: modify pipeline test Jasvinder Singh
@ 2015-10-21 12:18           ` Jasvinder Singh
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 6/6] example/ip_pipeline/pipeline: update flow_classification pipeline Jasvinder Singh
  5 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-21 12:18 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch adds parse_hex_string function to parse hex string to uint8_t
array.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 examples/ip_pipeline/config_parse.c | 70 +++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/pipeline.h     |  4 +++
 2 files changed, 74 insertions(+)

diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index c9b78f9..d7ee707 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -455,6 +455,76 @@ parse_pipeline_core(uint32_t *socket,
 	return 0;
 }
 
+static uint32_t
+get_hex_val(char c)
+{
+	switch (c) {
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+		return c - '0';
+	case 'A':
+	case 'B':
+	case 'C':
+	case 'D':
+	case 'E':
+	case 'F':
+		return c - 'A' + 10;
+	case 'a':
+	case 'b':
+	case 'c':
+	case 'd':
+	case 'e':
+	case 'f':
+		return c - 'a' + 10;
+	default:
+		return 0;
+	}
+}
+
+int
+parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
+{
+	char *c;
+	uint32_t len, i;
+
+	/* Check input parameters */
+	if ((src == NULL) ||
+		(dst == NULL) ||
+		(size == NULL) ||
+		(*size == 0))
+		return -1;
+
+	len = strlen(src);
+	if (((len & 3) != 0) ||
+		(len > (*size) * 2))
+		return -1;
+	*size = len / 2;
+
+	for (c = src; *c != 0; c++) {
+		if ((((*c) >= '0') && ((*c) <= '9')) ||
+			(((*c) >= 'A') && ((*c) <= 'F')) ||
+			(((*c) >= 'a') && ((*c) <= 'f')))
+			continue;
+
+		return -1;
+	}
+
+	/* Convert chars to bytes */
+	for (i = 0; i < *size; i++)
+		dst[i] = get_hex_val(src[2 * i]) * 16 +
+			get_hex_val(src[2 * i + 1]);
+
+	return 0;
+}
+
 static size_t
 skip_digits(const char *src)
 {
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index b9a56ea..4063594 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -84,4 +84,8 @@ pipeline_type_cmds_count(struct pipeline_type *ptype)
 	return n_cmds;
 }
 
+/* Parse hex string to uint8_t array */
+int
+parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
+
 #endif
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [dpdk-dev] [PATCH v3 6/6] example/ip_pipeline/pipeline: update flow_classification pipeline
  2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
                             ` (4 preceding siblings ...)
  2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 5/6] example/ip_pipeline: add parse_hex_string for internal use Jasvinder Singh
@ 2015-10-21 12:18           ` Jasvinder Singh
  5 siblings, 0 replies; 32+ messages in thread
From: Jasvinder Singh @ 2015-10-21 12:18 UTC (permalink / raw)
  To: dev

From: Fan Zhang <roy.fan.zhang@intel.com>

This patch updates the flow_classification pipeline for added key_mask
parameter in 8/16-byte key hash parameters. The update provides user
optional key_mask configuration item applying to the packets.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 .../pipeline/pipeline_flow_classification_be.c     | 56 ++++++++++++++++++++--
 1 file changed, 52 insertions(+), 4 deletions(-)

diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
index 06a648d..e22f96f 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
@@ -37,6 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_table_hash.h>
 #include <rte_byteorder.h>
+#include <pipeline.h>
 
 #include "pipeline_flow_classification_be.h"
 #include "hash_func.h"
@@ -49,6 +50,7 @@ struct pipeline_flow_classification {
 	uint32_t key_offset;
 	uint32_t key_size;
 	uint32_t hash_offset;
+	uint8_t *key_mask;
 } __rte_cache_aligned;
 
 static void *
@@ -125,8 +127,12 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 	uint32_t key_offset_present = 0;
 	uint32_t key_size_present = 0;
 	uint32_t hash_offset_present = 0;
+	uint32_t key_mask_present = 0;
 
 	uint32_t i;
+	char *key_mask_str = NULL;
+
+	p->hash_offset = 0;
 
 	for (i = 0; i < params->n_args; i++) {
 		char *arg_name = params->args_name[i];
@@ -171,6 +177,20 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 			continue;
 		}
 
+		/* key_mask */
+		if (strcmp(arg_name, "key_mask") == 0) {
+			if (key_mask_present)
+				return -1;
+
+			key_mask_str = strdup(arg_value);
+			if (key_mask_str == NULL)
+				return -1;
+
+			key_mask_present = 1;
+
+			continue;
+		}
+
 		/* hash_offset */
 		if (strcmp(arg_name, "hash_offset") == 0) {
 			if (hash_offset_present)
@@ -189,10 +209,23 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 	/* Check that mandatory arguments are present */
 	if ((n_flows_present == 0) ||
 		(key_offset_present == 0) ||
-		(key_size_present == 0) ||
-		(hash_offset_present == 0))
+		(key_size_present == 0))
 		return -1;
 
+	if (key_mask_present) {
+		p->key_mask = rte_malloc(NULL, p->key_size, 0);
+		if (p->key_mask == NULL)
+			return -1;
+
+		if (parse_hex_string(key_mask_str, p->key_mask, &p->key_size)
+			!= 0) {
+			free(p->key_mask);
+			return -1;
+		}
+
+		free(key_mask_str);
+	}
+
 	return 0;
 }
 
@@ -297,6 +330,7 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 			.signature_offset = p_fc->hash_offset,
 			.key_offset = p_fc->key_offset,
 			.f_hash = hash_func[(p_fc->key_size / 8) - 1],
+			.key_mask = p_fc->key_mask,
 			.seed = 0,
 		};
 
@@ -307,6 +341,7 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 			.signature_offset = p_fc->hash_offset,
 			.key_offset = p_fc->key_offset,
 			.f_hash = hash_func[(p_fc->key_size / 8) - 1],
+			.key_mask = p_fc->key_mask,
 			.seed = 0,
 		};
 
@@ -336,12 +371,25 @@ static void *pipeline_fc_init(struct pipeline_params *params,
 
 		switch (p_fc->key_size) {
 		case 8:
-			table_params.ops = &rte_table_hash_key8_lru_ops;
+			if (p_fc->hash_offset != 0) {
+				table_params.ops =
+					&rte_table_hash_key8_ext_ops;
+			} else {
+				table_params.ops =
+					&rte_table_hash_key8_ext_dosig_ops;
+			}
 			table_params.arg_create = &table_hash_key8_params;
 			break;
+			break;
 
 		case 16:
-			table_params.ops = &rte_table_hash_key16_ext_ops;
+			if (p_fc->hash_offset != 0) {
+				table_params.ops =
+					&rte_table_hash_key16_ext_ops;
+			} else {
+				table_params.ops =
+					&rte_table_hash_key16_ext_dosig_ops;
+			}
 			table_params.arg_create = &table_hash_key16_params;
 			break;
 
-- 
2.1.0

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2015-10-21 12:51 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-25 22:33 [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 2/8] librte_table: add key_mask parameter to 16-byte " roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 3/8] librte_table: add 16 byte hash table operations with computed lookup roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 4/8] app/test: modify app/test_table_combined and app/test_table_tables roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 5/8] app/test-pipeline: modify pipeline test roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 6/8] example/ip_pipeline: add parse_hex_string for internal use roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline roy.fan.zhang
2015-09-25 22:33 ` [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice roy.fan.zhang
2015-10-12 14:24   ` Thomas Monjalon
2015-10-12 16:30     ` Mcnamara, John
2015-10-13 13:57       ` [dpdk-dev] [PATCH v2 0/8] librte_table: add key_mask parameter to 8-byte key Jasvinder Singh
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 1/8] librte_table: add key_mask parameter to 8-byte key hash parameters Jasvinder Singh
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 2/8] librte_table: add key_mask parameter to 16-byte " Jasvinder Singh
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 3/8] librte_table: add 16 byte hash table operations with computed lookup Jasvinder Singh
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 4/8] app/test: modify app/test_table_combined and app/test_table_tables Jasvinder Singh
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 5/8] app/test-pipeline: modify pipeline test Jasvinder Singh
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 6/8] example/ip_pipeline: add parse_hex_string for internal use Jasvinder Singh
2015-10-19 13:49           ` Thomas Monjalon
2015-10-20 14:31             ` Dumitrescu, Cristian
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 7/8] example/ip_pipeline/pipeline: update flow_classification pipeline Jasvinder Singh
2015-10-19 13:57           ` Thomas Monjalon
2015-10-13 13:57         ` [dpdk-dev] [PATCH v2 8/8] librte_table: modify release notes and deprecation notice Jasvinder Singh
2015-10-21 12:18         ` [dpdk-dev] [PATCH v3 0/6] librte_table: add key_mask parameter to hash table parameter structure Jasvinder Singh
2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 1/6] librte_table: add key_mask parameter to 8- and 16-bytes key hash parameters Jasvinder Singh
2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 2/6] librte_table: add 16 byte hash table operations with computed lookup Jasvinder Singh
2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 3/6] app/test: modify app/test_table_combined and app/test_table_tables Jasvinder Singh
2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 4/6] app/test-pipeline: modify pipeline test Jasvinder Singh
2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 5/6] example/ip_pipeline: add parse_hex_string for internal use Jasvinder Singh
2015-10-21 12:18           ` [dpdk-dev] [PATCH v3 6/6] example/ip_pipeline/pipeline: update flow_classification pipeline Jasvinder Singh
2015-10-19 13:31       ` [dpdk-dev] [PATCH 8/8] librte_table: modify release notes and deprecation notice Thomas Monjalon
2015-09-28 20:07 ` [dpdk-dev] [PATCH 0/8] librte_table: add key_mask parameter to 8-byte key Dumitrescu, Cristian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).