[dpdk-dev] [PATCH] maintainers: update testpmd maintainers

2016-11-23 Thread Wei Dai
add Jingjing Wu and Wei Dai as new maintainers
of test-pmd.

Signed-off-by: Wei Dai 
---
 MAINTAINERS | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d6bb8f8..8070ed6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -614,7 +614,8 @@ F: app/test/virtual_pmd.c
 F: app/test/virtual_pmd.h

 Driver testing tool
-M: Pablo de Lara 
+M: Jingjing Wu 
+M: Wei Dai 
 F: app/test-pmd/
 F: doc/guides/testpmd_app_ug/

-- 
2.7.4



[dpdk-dev] [PATCH v3] eal/linuxapp: fix return value check of mknod()

2016-11-17 Thread Wei Dai
In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c,
The return value of mknod() is ret, not f got by fopen().
So the value of ret should be checked for mknod().

Fixes: f7f97c16048e ("pci: add option --create-uio-dev to run without hotplug")

Signed-off-by: Wei Dai 
---
v3:
* correct Fixes: line in git commit message body

v2:
* fix my local git setting and send same patch again to remove
  "From: Wei Dai " in git commit message body
  and make merging easier

 lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c 
b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..3e4ffb5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned 
uio_num)
snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
dev = makedev(major, minor);
ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-   if (f == NULL) {
+   if (ret != 0) {
RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
__func__, strerror(errno));
return -1;
-- 
2.5.5



[dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread Wei Dai
In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c,
The return value of mknod() is ret, not f got by fopen().
So the value of ret should be checked for mknod().

Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")

Signed-off-by: Wei Dai 
---
fix my local git setting and send same patch again to
make merging easier

 lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c 
b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..3e4ffb5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned 
uio_num)
snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
dev = makedev(major, minor);
ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-   if (f == NULL) {
+   if (ret != 0) {
RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
__func__, strerror(errno));
return -1;
-- 
2.5.5



[dpdk-dev] [PATCH] lpm: fix freeing memory

2016-11-03 Thread Wei Dai
The memory pointed by lpm->rules_tbl should also be freed
when memory malloc for tbl8 fails in rte_lpm_create_v1604( ).
And the memory pointed by lpm->tbl8 should also be freed
when the lpm object is freed in rte_lpm_free_v1604( ).

Fixes: f1f7261838b3 ("lpm: add a new config structure for IPv4")

Signed-off-by: Morten Br?rup 
Signed-off-by: Wei Dai 
---
 lib/librte_lpm/rte_lpm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index ec67765..8c15c4c 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -321,6 +321,7 @@ rte_lpm_create_v1604(const char *name, int socket_id,

if (lpm->tbl8 == NULL) {
RTE_LOG(ERR, LPM, "LPM tbl8 memory allocation failed\n");
+   rte_free(lpm->rules_tbl);
rte_free(lpm);
lpm = NULL;
rte_free(te);
@@ -402,6 +403,7 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)

rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);

+   rte_free(lpm->tbl8);
rte_free(lpm->rules_tbl);
rte_free(lpm);
rte_free(te);
-- 
2.7.4



[dpdk-dev] [PATCH] mempool: fix search of maximum contiguous pages

2016-10-13 Thread Wei Dai
paddr[i] + pg_sz always points to the start physical address of the
2nd page after pddr[i], so only up to 2 pages can be combinded to
be used. With this revision, more than 2 pages can be used.

Fixes: 84121f197187 ("mempool: store memory chunks in a list")

Signed-off-by: Wei Dai 
---
 lib/librte_mempool/rte_mempool.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 71017e1..e3e254a 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -426,9 +426,12 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char 
*vaddr,

for (i = 0; i < pg_num && mp->populated_size < mp->size; i += n) {

+   phys_addr_t paddr_next;
+   paddr_next = paddr[i] + pg_sz;
+
/* populate with the largest group of contiguous pages */
for (n = 1; (i + n) < pg_num &&
-paddr[i] + pg_sz == paddr[i+n]; n++)
+paddr_next == paddr[i+n]; n++, paddr_next += pg_sz)
;

ret = rte_mempool_populate_phys(mp, vaddr + i * pg_sz,
-- 
2.7.4



[dpdk-dev] [PATCH] ethdev: fix statistics description

2016-08-26 Thread Wei Dai
Add comments to describe that not all statistics fields in
struct rte_eth_stats are supported by any type of network
interface card. If any statistics field is not supported,
its value is 0.

Fixes: af75078fece3 ("first public release")

Signed-off-by: Wei Dai 
---
 lib/librte_ether/rte_ethdev.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b0fe033..653e36c 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -190,6 +190,9 @@ struct rte_mbuf;

 /**
  * A structure used to retrieve statistics for an Ethernet port.
+ * Not all statistics fields in struct rte_eth_stats are supported
+ * by any type of network interface card (NIC). If any statistics
+ * field is not supported, its value is 0 .
  */
 struct rte_eth_stats {
uint64_t ipackets;  /**< Total number of successfully received packets. 
*/
-- 
2.7.4



[dpdk-dev] [PATCH v4 3/3] lpm: remove redundant check when adding lpm rule

2016-08-08 Thread Wei Dai
When a rule with depth > 24 is added into an existing
rule with depth <=24, a new tbl8 is allocated, the existing
rule first fulfill whole new tbl8, so the filed valid of
each entry in this tbl8 is always true and depth of each
entry is always <= 24 before adding the new rule with depth > 24.

Signed-off-by: Wei Dai 
Acked-by: Bruce Richardson 
---
 lib/librte_lpm/rte_lpm.c | 22 ++
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 24fec4b..ec67765 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -940,14 +940,9 @@ add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t 
ip_masked, uint8_t depth,

/* Insert new rule into the tbl8 entry. */
for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
-   if (!lpm->tbl8[i].valid ||
-   lpm->tbl8[i].depth <= depth) {
-   lpm->tbl8[i].valid = VALID;
-   lpm->tbl8[i].depth = depth;
-   lpm->tbl8[i].next_hop = next_hop;
-
-   continue;
-   }
+   lpm->tbl8[i].valid = VALID;
+   lpm->tbl8[i].depth = depth;
+   lpm->tbl8[i].next_hop = next_hop;
}

/*
@@ -1071,14 +1066,9 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t 
ip_masked, uint8_t depth,

/* Insert new rule into the tbl8 entry. */
for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
-   if (!lpm->tbl8[i].valid ||
-   lpm->tbl8[i].depth <= depth) {
-   lpm->tbl8[i].valid = VALID;
-   lpm->tbl8[i].depth = depth;
-   lpm->tbl8[i].next_hop = next_hop;
-
-   continue;
-   }
+   lpm->tbl8[i].valid = VALID;
+   lpm->tbl8[i].depth = depth;
+   lpm->tbl8[i].next_hop = next_hop;
}

/*
-- 
2.5.5



[dpdk-dev] [PATCH v4 2/3] app/test: add a case to verify lpm tlb8 recycle

2016-08-08 Thread Wei Dai
As a bug-fix for lpm tlb8 recycle is introduced,
add a test case to verify tlb8 group is correctly
freed when it only includes a rule with depth=24.

Signed-off-by: Wei Dai 
Acked-by: Bruce Richardson 
---
 app/test/test_lpm.c | 80 -
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index b6ad2eb..ad12846 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -68,6 +68,7 @@ static int32_t test14(void);
 static int32_t test15(void);
 static int32_t test16(void);
 static int32_t test17(void);
+static int32_t test18(void);

 rte_lpm_test tests[] = {
 /* Test Cases */
@@ -89,6 +90,7 @@ rte_lpm_test tests[] = {
test15,
test16,
test17,
+   test18
 };

 #define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0]))
@@ -1218,6 +1220,82 @@ test17(void)
 }

 /*
+ * Test for recycle of tlb8
+ *  - step 1: add a rule with depth=28 (> 24)
+ *  - step 2: add a rule with same 24-bit prefix and depth=23 (< 24)
+ *  - step 3: delete the first rule
+ *  - step 4: check tlb8 is freed
+ *  - step 5: add a rule same as the first one (depth=28)
+ *  - step 6: check same tlb8 is allocated
+ *  - step 7: add a rule with same 24-bit prefix and depth=24
+ *  - step 8: delete the rule (depth=28) added in step 5
+ *  - step 9: check tlb8 is freed
+ *  - step 10: add a rule with same 24-bit prefix and depth = 28
+ *  - setp 11: check same tlb8 is allocated again
+ */
+int32_t
+test18(void)
+{
+#define group_idx next_hop
+   struct rte_lpm *lpm = NULL;
+   struct rte_lpm_config config;
+   uint32_t ip, next_hop;
+   uint8_t depth;
+   uint32_t tbl8_group_index;
+
+   config.max_rules = MAX_RULES;
+   config.number_tbl8s = NUMBER_TBL8S;
+   config.flags = 0;
+
+   lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, );
+   TEST_LPM_ASSERT(lpm != NULL);
+
+   ip = IPv4(192, 168, 100, 100);
+   depth = 28;
+   next_hop = 1;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   tbl8_group_index = lpm->tbl8[ip>>8].group_idx;
+
+   depth = 23;
+   next_hop = 2;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+
+   depth = 28;
+   rte_lpm_delete(lpm, ip, depth);
+
+   TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group);
+
+   next_hop = 3;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl8[ip>>8].group_idx);
+
+   depth = 24;
+   next_hop = 4;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+
+   depth = 28;
+   rte_lpm_delete(lpm, ip, depth);
+
+   TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group);
+
+   next_hop = 5;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl8[ip>>8].group_idx);
+
+   rte_lpm_free(lpm);
+#undef group_idx
+   return PASS;
+}
+
+/*
  * Do all unit tests.
  */

@@ -1230,7 +1308,7 @@ test_lpm(void)
for (i = 0; i < NUM_LPM_TESTS; i++) {
status = tests[i]();
if (status < 0) {
-   printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests[i]));
+   printf("ERROR: LPM Test %u: FAIL\n", i);
global_status = status;
}
}
-- 
2.5.5



[dpdk-dev] [PATCH v4 1/3] lpm: fix freeing unused sub-table on rule delete

2016-08-08 Thread Wei Dai
When all rules with depth > 24 are deleted in a same sub-table
(tlb8 group) and only a rule with depth <=24 is left in it,
this sub-table (tlb8 group) should be recycled.

Fixes: dc81ebbacaeb ("lpm: extend IPv4 next hop field")
Fixes: af75078fece3 ("first public release")

Signed-off-by: Wei Dai 
Acked-by: Bruce Richardson 
---
 lib/librte_lpm/rte_lpm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 6f65d1c..24fec4b 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -1533,7 +1533,7 @@ tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
 * and if so check the rest of the entries to verify that they
 * are all of this depth.
 */
-   if (tbl8[tbl8_group_start].depth < MAX_DEPTH_TBL24) {
+   if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
for (i = (tbl8_group_start + 1); i < tbl8_group_end;
i++) {

@@ -1580,7 +1580,7 @@ tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
 * and if so check the rest of the entries to verify that they
 * are all of this depth.
 */
-   if (tbl8[tbl8_group_start].depth < MAX_DEPTH_TBL24) {
+   if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
for (i = (tbl8_group_start + 1); i < tbl8_group_end;
i++) {

-- 
2.5.5



[dpdk-dev] [PATCH v3 3/3] lpm: remove redundant check when adding lpm rule

2016-08-03 Thread Wei Dai
When a rule with depth > 24 is added into an existing
rule with depth <=24, a new tbl8 is allocated, the existing
rule first fulfill whole new tbl8, so the filed valid of
each entry in this tbl8 is always true and depth of each
entry is always <= 24 before adding the new rule with depth > 24.

Signed-off-by: Wei Dai 
---
 lib/librte_lpm/rte_lpm.c | 22 ++
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 24fec4b..ec67765 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -940,14 +940,9 @@ add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t 
ip_masked, uint8_t depth,

/* Insert new rule into the tbl8 entry. */
for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
-   if (!lpm->tbl8[i].valid ||
-   lpm->tbl8[i].depth <= depth) {
-   lpm->tbl8[i].valid = VALID;
-   lpm->tbl8[i].depth = depth;
-   lpm->tbl8[i].next_hop = next_hop;
-
-   continue;
-   }
+   lpm->tbl8[i].valid = VALID;
+   lpm->tbl8[i].depth = depth;
+   lpm->tbl8[i].next_hop = next_hop;
}

/*
@@ -1071,14 +1066,9 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t 
ip_masked, uint8_t depth,

/* Insert new rule into the tbl8 entry. */
for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
-   if (!lpm->tbl8[i].valid ||
-   lpm->tbl8[i].depth <= depth) {
-   lpm->tbl8[i].valid = VALID;
-   lpm->tbl8[i].depth = depth;
-   lpm->tbl8[i].next_hop = next_hop;
-
-   continue;
-   }
+   lpm->tbl8[i].valid = VALID;
+   lpm->tbl8[i].depth = depth;
+   lpm->tbl8[i].next_hop = next_hop;
}

/*
-- 
2.5.5



[dpdk-dev] [PATCH v3 2/3] app/test: add a case to verify lpm tlb8 recycle

2016-08-03 Thread Wei Dai
As a bug-fix for lpm tlb8 recycle is introduced,
add a test case to verify tlb8 group is correctly
freed when it only includes a rule with depth=24.

Signed-off-by: Wei Dai 
---
 app/test/test_lpm.c | 80 -
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index b6ad2eb..ad12846 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -68,6 +68,7 @@ static int32_t test14(void);
 static int32_t test15(void);
 static int32_t test16(void);
 static int32_t test17(void);
+static int32_t test18(void);

 rte_lpm_test tests[] = {
 /* Test Cases */
@@ -89,6 +90,7 @@ rte_lpm_test tests[] = {
test15,
test16,
test17,
+   test18
 };

 #define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0]))
@@ -1218,6 +1220,82 @@ test17(void)
 }

 /*
+ * Test for recycle of tlb8
+ *  - step 1: add a rule with depth=28 (> 24)
+ *  - step 2: add a rule with same 24-bit prefix and depth=23 (< 24)
+ *  - step 3: delete the first rule
+ *  - step 4: check tlb8 is freed
+ *  - step 5: add a rule same as the first one (depth=28)
+ *  - step 6: check same tlb8 is allocated
+ *  - step 7: add a rule with same 24-bit prefix and depth=24
+ *  - step 8: delete the rule (depth=28) added in step 5
+ *  - step 9: check tlb8 is freed
+ *  - step 10: add a rule with same 24-bit prefix and depth = 28
+ *  - setp 11: check same tlb8 is allocated again
+ */
+int32_t
+test18(void)
+{
+#define group_idx next_hop
+   struct rte_lpm *lpm = NULL;
+   struct rte_lpm_config config;
+   uint32_t ip, next_hop;
+   uint8_t depth;
+   uint32_t tbl8_group_index;
+
+   config.max_rules = MAX_RULES;
+   config.number_tbl8s = NUMBER_TBL8S;
+   config.flags = 0;
+
+   lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, );
+   TEST_LPM_ASSERT(lpm != NULL);
+
+   ip = IPv4(192, 168, 100, 100);
+   depth = 28;
+   next_hop = 1;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   tbl8_group_index = lpm->tbl8[ip>>8].group_idx;
+
+   depth = 23;
+   next_hop = 2;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+
+   depth = 28;
+   rte_lpm_delete(lpm, ip, depth);
+
+   TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group);
+
+   next_hop = 3;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl8[ip>>8].group_idx);
+
+   depth = 24;
+   next_hop = 4;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+
+   depth = 28;
+   rte_lpm_delete(lpm, ip, depth);
+
+   TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group);
+
+   next_hop = 5;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl8[ip>>8].group_idx);
+
+   rte_lpm_free(lpm);
+#undef group_idx
+   return PASS;
+}
+
+/*
  * Do all unit tests.
  */

@@ -1230,7 +1308,7 @@ test_lpm(void)
for (i = 0; i < NUM_LPM_TESTS; i++) {
status = tests[i]();
if (status < 0) {
-   printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests[i]));
+   printf("ERROR: LPM Test %u: FAIL\n", i);
global_status = status;
}
}
-- 
2.5.5



[dpdk-dev] [PATCH v3 1/3] lpm: fix freeing unused sub-table on rule delete

2016-08-03 Thread Wei Dai
When all rules with depth > 24 are deleted in a same sub-table
(tlb8 group) and only a rule with depth <=24 is left in it,
this sub-table (tlb8 group) should be recycled.

Fixes: dc81ebbacaeb ("lpm: extend IPv4 next hop field")
Fixes: af75078fece3 ("first public release")

Signed-off-by: Wei Dai 
---
 lib/librte_lpm/rte_lpm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 6f65d1c..24fec4b 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -1533,7 +1533,7 @@ tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
 * and if so check the rest of the entries to verify that they
 * are all of this depth.
 */
-   if (tbl8[tbl8_group_start].depth < MAX_DEPTH_TBL24) {
+   if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
for (i = (tbl8_group_start + 1); i < tbl8_group_end;
i++) {

@@ -1580,7 +1580,7 @@ tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
 * and if so check the rest of the entries to verify that they
 * are all of this depth.
 */
-   if (tbl8[tbl8_group_start].depth < MAX_DEPTH_TBL24) {
+   if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
for (i = (tbl8_group_start + 1); i < tbl8_group_end;
i++) {

-- 
2.5.5



[dpdk-dev] [PATCH v2] lpm: remove redundant check when adding lpm rule

2016-08-02 Thread Wei Dai
When a rule with depth > 24 is added into an existing
rule with depth <=24, a new tbl8 is allocated, the existing
rule first fulfill whole new tbl8, so the filed vaild of
each entry in this tbl8 is always true and depth of each
entry is always < 24 before adding new rule with depth > 24.

Signed-off-by: Wei Dai 
---
 lib/librte_lpm/rte_lpm.c | 22 ++
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 24fec4b..ec67765 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -931,32 +931,27 @@ add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t 
ip_masked, uint8_t depth,
/* Populate new tbl8 with tbl24 value. */
for (i = tbl8_group_start; i < tbl8_group_end; i++) {
lpm->tbl8[i].valid = VALID;
lpm->tbl8[i].depth = lpm->tbl24[tbl24_index].depth;
lpm->tbl8[i].next_hop =
lpm->tbl24[tbl24_index].next_hop;
}

tbl8_index = tbl8_group_start + (ip_masked & 0xFF);

/* Insert new rule into the tbl8 entry. */
for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
-   if (!lpm->tbl8[i].valid ||
-   lpm->tbl8[i].depth <= depth) {
-   lpm->tbl8[i].valid = VALID;
-   lpm->tbl8[i].depth = depth;
-   lpm->tbl8[i].next_hop = next_hop;
-
-   continue;
-   }
+   lpm->tbl8[i].valid = VALID;
+   lpm->tbl8[i].depth = depth;
+   lpm->tbl8[i].next_hop = next_hop;
}

/*
 * Update tbl24 entry to point to new tbl8 entry. Note: The
 * ext_flag and tbl8_index need to be updated simultaneously,
 * so assign whole structure in one go.
 */

struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
{ .group_idx = (uint8_t)tbl8_group_index, },
.valid = VALID,
.valid_group = 1,
@@ -1062,32 +1057,27 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t 
ip_masked, uint8_t depth,
/* Populate new tbl8 with tbl24 value. */
for (i = tbl8_group_start; i < tbl8_group_end; i++) {
lpm->tbl8[i].valid = VALID;
lpm->tbl8[i].depth = lpm->tbl24[tbl24_index].depth;
lpm->tbl8[i].next_hop =
lpm->tbl24[tbl24_index].next_hop;
}

tbl8_index = tbl8_group_start + (ip_masked & 0xFF);

/* Insert new rule into the tbl8 entry. */
for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
-   if (!lpm->tbl8[i].valid ||
-   lpm->tbl8[i].depth <= depth) {
-   lpm->tbl8[i].valid = VALID;
-   lpm->tbl8[i].depth = depth;
-   lpm->tbl8[i].next_hop = next_hop;
-
-   continue;
-   }
+   lpm->tbl8[i].valid = VALID;
+   lpm->tbl8[i].depth = depth;
+   lpm->tbl8[i].next_hop = next_hop;
}

/*
 * Update tbl24 entry to point to new tbl8 entry. Note: The
 * ext_flag and tbl8_index need to be updated simultaneously,
 * so assign whole structure in one go.
 */

struct rte_lpm_tbl_entry new_tbl24_entry = {
.group_idx = (uint8_t)tbl8_group_index,
.valid = VALID,
.valid_group = 1,
-- 
2.5.5



[dpdk-dev] [PATCH] lpm: remove redundant check when adding lpm rule

2016-08-01 Thread Wei Dai
When a rule with depth > 24 is added into an existing
rule with depth <=24, a new tbl8 is allocated, the existing
rule first fulfill whole new tbl8, so the filed vaild of
each entry in this tbl8 is always true and depth of each
entry is always < 24 before adding new rule with depth > 24.

Signed-off-by: Wei Dai 
---
 lib/librte_lpm/rte_lpm.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 24fec4b..5bdc23f 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -1071,14 +1071,9 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t 
ip_masked, uint8_t depth,

/* Insert new rule into the tbl8 entry. */
for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
-   if (!lpm->tbl8[i].valid ||
-   lpm->tbl8[i].depth <= depth) {
-   lpm->tbl8[i].valid = VALID;
-   lpm->tbl8[i].depth = depth;
-   lpm->tbl8[i].next_hop = next_hop;
-
-   continue;
-   }
+   lpm->tbl8[i].valid = VALID;
+   lpm->tbl8[i].depth = depth;
+   lpm->tbl8[i].next_hop = next_hop;
}

/*
-- 
2.5.5



[dpdk-dev] [PATCH 2/2] app/test: add a case to verify lpm tlb8 recycle

2016-08-01 Thread Wei Dai
As a bug-fix for lpm tlb8 recycle is introduced,
add a test case to verify tlb8 group is correctly
freed when it only includes a rule with depth=24.

Signed-off-by: Wei Dai 
---
 app/test/test_lpm.c | 81 -
 1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index b6ad2eb..e053f99 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -68,6 +68,7 @@ static int32_t test14(void);
 static int32_t test15(void);
 static int32_t test16(void);
 static int32_t test17(void);
+static int32_t test18(void);

 rte_lpm_test tests[] = {
 /* Test Cases */
@@ -89,6 +90,7 @@ rte_lpm_test tests[] = {
test15,
test16,
test17,
+   test18
 };

 #define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0]))
@@ -1218,6 +1220,83 @@ test17(void)
 }

 /*
+ * Test for recycle of tlb8
+ *  - step 1: add a rule with depth=28 (> 24)
+ *  - step 2: add a rule with same 24-bit prefix and depth=23 (< 24)
+ *  - step 3: delete the first rule
+ *  - step 4: check tlb8 is freed
+ *  - step 5: add a rule same as the first one (depth=28)
+ *  - step 6: check same tlb8 is allocated
+ *  - step 7: add a rule with same 24-bit prefix and depth=24
+ *  - step 8: delete the rule (depth=28) added in step 5
+ *  - step 9: check tlb8 is freed
+ *  - step 10: add a rule with same 24-bit prefix and depth = 28
+ *  - setp 11: check same tlb8 is allocated again
+ */
+int32_t
+test18(void)
+{
+#define group_idx next_hop
+   struct rte_lpm *lpm = NULL;
+   struct rte_lpm_config config;
+   uint32_t ip, next_hop;
+   uint8_t depth;
+   uint32_t tbl8_group_index;
+
+   config.max_rules = MAX_RULES;
+   config.number_tbl8s = NUMBER_TBL8S;
+   config.flags = 0;
+
+   lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, );
+   TEST_LPM_ASSERT(lpm != NULL);
+
+   ip = IPv4(192, 168, 100, 100);
+   depth = 28;
+   next_hop = 1;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   tbl8_group_index = lpm->tbl8[ip>>8].group_idx;
+
+   depth = 23;
+   next_hop = 2;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+
+   depth = 28;
+   rte_lpm_delete(lpm, ip, depth);
+
+   TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group);
+
+   next_hop = 3;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl8[ip>>8].group_idx);
+
+   depth = 24;
+   next_hop = 4;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+
+   depth = 28;
+   rte_lpm_delete(lpm, ip, depth);
+
+   TEST_LPM_ASSERT(!lpm->tbl24[ip>>8].valid_group);
+
+   next_hop = 5;
+   rte_lpm_add(lpm, ip, depth, next_hop);
+
+   TEST_LPM_ASSERT(lpm->tbl24[ip>>8].valid_group);
+   TEST_LPM_ASSERT(tbl8_group_index == lpm->tbl8[ip>>8].group_idx);
+
+   rte_lpm_free(lpm);
+#undef group_idx
+   return PASS;
+}
+
+
+/*
  * Do all unit tests.
  */

@@ -1230,7 +1309,7 @@ test_lpm(void)
for (i = 0; i < NUM_LPM_TESTS; i++) {
status = tests[i]();
if (status < 0) {
-   printf("ERROR: LPM Test %s: FAIL\n", RTE_STR(tests[i]));
+   printf("ERROR: LPM Test %u: FAIL\n", i);
global_status = status;
}
}
-- 
2.5.5



[dpdk-dev] [PATCH 1/2] lpm: fix tlb8 only not freed for depth=24

2016-08-01 Thread Wei Dai
When all rules with depth > 24 are deleted in a same tlb8 group
and only leave a rule with depth <= 24 in this group, the tlb8
group should be recycled.

Fixes: af75078fece3 ("first public release")

Signed-off-by: Wei Dai 
---
 lib/librte_lpm/rte_lpm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 6f65d1c..24fec4b 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -1533,7 +1533,7 @@ tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
 * and if so check the rest of the entries to verify that they
 * are all of this depth.
 */
-   if (tbl8[tbl8_group_start].depth < MAX_DEPTH_TBL24) {
+   if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
for (i = (tbl8_group_start + 1); i < tbl8_group_end;
i++) {

@@ -1580,7 +1580,7 @@ tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
 * and if so check the rest of the entries to verify that they
 * are all of this depth.
 */
-   if (tbl8[tbl8_group_start].depth < MAX_DEPTH_TBL24) {
+   if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
for (i = (tbl8_group_start + 1); i < tbl8_group_end;
i++) {

-- 
2.5.5



[dpdk-dev] [PATCH v3 4/4] eal: fix end character check in --lcores argument

2016-07-27 Thread Wei Dai
With --lcores 'a-b at c-d', eal_parse_cores() fails because
eal_parse_set() fails due to the next character after
lcore set a-b, which is '@'and not ',' or '\0'.
There is also a right check immediately
after this incorrect check.

Fixes: 53e54bf81700 ("eal: new option --lcores for cpu assignment")

Signed-off-by: Wei Dai 
---
 lib/librte_eal/common/eal_common_options.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index 1a1bab3..f443a61 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -469,8 +469,6 @@ eal_parse_set(const char *input, uint16_t set[], unsigned 
num)
max = idx;
while (isblank(*end))
end++;
-   if (*end != ',' && *end != '\0')
-   return -1;
}

if (*end != ',' && *end != '\0' &&
-- 
2.5.5



[dpdk-dev] [PATCH v3 3/4] eal: fix tail blank check in --lcores argument

2016-07-27 Thread Wei Dai
the tail blank after a group of lcore or cpu set
will make check of its end character fail.
for example: --lcores '(0-3)@(0-3)   ,(4-5)@(4-5)',
the next character after cpu set (0-3) is not ','
or '\0', which fail the check in eal_parse_lcores( ).

Fixes: 53e54bf81700 ("eal: new option --lcores for cpu assignment")

Signed-off-by: Wei Dai 
---
 lib/librte_eal/common/eal_common_options.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index 217d08b..1a1bab3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -530,6 +530,13 @@ eal_parse_set(const char *input, uint16_t set[], unsigned 
num)
str = end + 1;
} while (*end != '\0' && *end != ')');

+   /*
+* to avoid failure that tail blank makes end character check fail
+* in eal_parse_lcores( )
+*/
+   while (isblank(*str))
+   str++;
+
return str - input;
 }

-- 
2.5.5



[dpdk-dev] [PATCH v3 2/4] eal: fix parsing of eal option --lcores

2016-07-27 Thread Wei Dai
The '-' in lcore set overrides cpu set of following
lcore set in the argument of EAL option --lcores.
for example --locres '0-2,(3-5)@(3,4),6@(5,6),7@(5-7)',
0-2 make lflags=1 which indeed suppress following
cpu set (3,4), (5,6) and (5-7) after @ .

Fixes: 53e54bf81700 ("eal: new option --lcores for cpu assignment")

Signed-off-by: Wei Dai 
---
 lib/librte_eal/common/eal_common_options.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index c5bf98c..217d08b 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -583,7 +583,7 @@ eal_parse_lcores(const char *lcores)
const char *end = NULL;
int offset;
rte_cpuset_t cpuset;
-   int lflags = 0;
+   int lflags;
int ret = -1;

if (lcores == NULL)
@@ -609,6 +609,8 @@ eal_parse_lcores(const char *lcores)
if (*lcores == '\0')
goto err;

+   lflags = 0;
+
/* record lcore_set start point */
lcore_start = lcores;

-- 
2.5.5



[dpdk-dev] [PATCH v3 1/4] eal: remove redundant codes to parse --lcores

2016-07-27 Thread Wei Dai
local variable i is not referred by other codes in
the function eal_parse_lcores( ), so it can be removed.

Signed-off-by: Wei Dai 
---
 lib/librte_eal/common/eal_common_options.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index 481c732..c5bf98c 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -578,7 +578,6 @@ eal_parse_lcores(const char *lcores)
struct rte_config *cfg = rte_eal_get_configuration();
static uint16_t set[RTE_MAX_LCORE];
unsigned idx = 0;
-   int i;
unsigned count = 0;
const char *lcore_start = NULL;
const char *end = NULL;
@@ -593,9 +592,6 @@ eal_parse_lcores(const char *lcores)
/* Remove all blank characters ahead and after */
while (isblank(*lcores))
lcores++;
-   i = strlen(lcores);
-   while ((i > 0) && isblank(lcores[i - 1]))
-   i--;

CPU_ZERO();

-- 
2.5.5



[dpdk-dev] [PATCH v2 2/2] eal: fix parsing of eal option --lcores

2016-07-26 Thread Wei Dai
The '-' in lcore set overrides cpu set of following
lcore set in the argument of EAL option --lcores.
for example --locres '0-2,(3-5)@(3,4),6@(5,6),7@(5-7)',
0-2 make lflags=1 which indeed suppress following
cpu set (3,4), (5,6) and (5-7) after @ .

Fixes: 53e54bf81700 ("eal: new option --lcores for cpu assignment")

Signed-off-by: Wei Dai 
---
 lib/librte_eal/common/eal_common_options.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index c5bf98c..217d08b 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -583,7 +583,7 @@ eal_parse_lcores(const char *lcores)
const char *end = NULL;
int offset;
rte_cpuset_t cpuset;
-   int lflags = 0;
+   int lflags;
int ret = -1;

if (lcores == NULL)
@@ -609,6 +609,8 @@ eal_parse_lcores(const char *lcores)
if (*lcores == '\0')
goto err;

+   lflags = 0;
+
/* record lcore_set start point */
lcore_start = lcores;

-- 
2.5.5



[dpdk-dev] [PATCH v2 1/2] eal: remove redundant codes to parse --lcores

2016-07-26 Thread Wei Dai
local variable i is not referred by other codes in
the function eal_parse_lcores( ), so it can be removed.

Signed-off-by: Wei Dai 
---
 lib/librte_eal/common/eal_common_options.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index 481c732..c5bf98c 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -578,7 +578,6 @@ eal_parse_lcores(const char *lcores)
struct rte_config *cfg = rte_eal_get_configuration();
static uint16_t set[RTE_MAX_LCORE];
unsigned idx = 0;
-   int i;
unsigned count = 0;
const char *lcore_start = NULL;
const char *end = NULL;
@@ -593,9 +592,6 @@ eal_parse_lcores(const char *lcores)
/* Remove all blank characters ahead and after */
while (isblank(*lcores))
lcores++;
-   i = strlen(lcores);
-   while ((i > 0) && isblank(lcores[i - 1]))
-   i--;

CPU_ZERO();

-- 
2.5.5



[dpdk-dev] [PATCH] eal: fix parsing of argument of option --lcores

2016-07-21 Thread Wei Dai
The '-' in lcores set overrides cpu set of following
lcore set in the argument of EAL option --lcores.

Fixes: 53e54bf81700 ("eal: new option --lcores for cpu assignment")

Signed-off-by: Wei Dai 
---
 lib/librte_eal/common/eal_common_options.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_options.c 
b/lib/librte_eal/common/eal_common_options.c
index 0a594d7..96eb1a9 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -563,6 +563,7 @@ convert_to_cpuset(rte_cpuset_t *cpusetp,
  * lcores, cpus could be a single digit/range or a group.
  * '(' and ')' are necessary if it's a group.
  * If not supply '@cpus', the value of cpus uses the same as lcores.
+ * The 'a-b' in lcores not within '(' and ')' means a,a+1,...,b-1,b .
  * e.g. '1,2@(5-7),(3-5)@(0,2),(0,6),7-8' means start 9 EAL thread as below
  *   lcore 0 runs on cpuset 0x41 (cpu 0,6)
  *   lcore 1 runs on cpuset 0x2 (cpu 1)
@@ -571,6 +572,15 @@ convert_to_cpuset(rte_cpuset_t *cpusetp,
  *   lcore 6 runs on cpuset 0x41 (cpu 0,6)
  *   lcore 7 runs on cpuset 0x80 (cpu 7)
  *   lcore 8 runs on cpuset 0x100 (cpu 8)
+ * e.g. '0-2,(3-5)@(3,4),6@(5,6),7@(5-7)'means start 8 EAL threads as below
+ *   lcore 0 runs on cpuset 0x1 (cpu 0)
+ *   lcore 1 runs on cpuset 0x2 (cpu 1)
+ *   lcore 2 runs on cpuset ox4 (cpu 2)
+ *   lcore 3,4,5 runs on cpuset 0x18 (cpu 3,4)
+ *   lcore 6 runs on cpuset 0x60 (cpu 5,6)
+ *   lcore 7 runs on cpuset 0xe0 (cpu 5,6,7)
+ * The second case is used to test bugfix for lflags not be cleared after use
+ */
  */
 static int
 eal_parse_lcores(const char *lcores)
@@ -679,6 +689,8 @@ eal_parse_lcores(const char *lcores)
   sizeof(rte_cpuset_t));
}

+   lflags = 0;
+
lcores = end + 1;
} while (*end != '\0');

-- 
2.5.5