* [dpdk-dev] [PATCH 1/2] lpm: added a new rte_lpm_config structure for ipv4
2016-03-08 20:57 [dpdk-dev] [PATCH 0/2] Added a new rte_lpm_config structure for IPv4 Michal Kobylinski
@ 2016-03-08 20:57 ` Michal Kobylinski
2016-03-08 20:57 ` [dpdk-dev] [PATCH 2/2] examples: update to use new rte_lpm_config " Michal Kobylinski
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Michal Kobylinski @ 2016-03-08 20:57 UTC (permalink / raw)
To: dev
Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
app/test/test_func_reentrancy.c | 9 +-
app/test/test_lpm.c | 145 +++++++++++++++++++++++++++------
app/test/test_mp_secondary.c | 7 +-
app/test/test_table_combined.c | 2 +
app/test/test_table_tables.c | 2 +
doc/guides/rel_notes/release_16_04.rst | 5 ++
lib/librte_lpm/rte_lpm.c | 51 +++++++++---
lib/librte_lpm/rte_lpm.h | 23 ++++--
lib/librte_table/rte_table_lpm.c | 12 ++-
lib/librte_table/rte_table_lpm.h | 6 ++
10 files changed, 215 insertions(+), 47 deletions(-)
diff --git a/app/test/test_func_reentrancy.c b/app/test/test_func_reentrancy.c
index dbecc52..5d09296 100644
--- a/app/test/test_func_reentrancy.c
+++ b/app/test/test_func_reentrancy.c
@@ -359,6 +359,11 @@ lpm_create_free(__attribute__((unused)) void *arg)
{
unsigned lcore_self = rte_lcore_id();
struct rte_lpm *lpm;
+ struct rte_lpm_config config;
+
+ config.max_rules = 4;
+ config.number_tbl8s = 256;
+ config.flags = 0;
char lpm_name[MAX_STRING_SIZE];
int i;
@@ -366,7 +371,7 @@ lpm_create_free(__attribute__((unused)) void *arg)
/* create the same lpm simultaneously on all threads */
for (i = 0; i < MAX_ITER_TIMES; i++) {
- lpm = rte_lpm_create("fr_test_once", SOCKET_ID_ANY, 4, 0);
+ lpm = rte_lpm_create("fr_test_once", SOCKET_ID_ANY, &config);
if ((NULL == lpm) && (rte_lpm_find_existing("fr_test_once") == NULL))
return -1;
}
@@ -374,7 +379,7 @@ lpm_create_free(__attribute__((unused)) void *arg)
/* create mutiple fbk tables simultaneously */
for (i = 0; i < MAX_LPM_ITER_TIMES; i++) {
snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_self, i);
- lpm = rte_lpm_create(lpm_name, SOCKET_ID_ANY, 4, 0);
+ lpm = rte_lpm_create(lpm_name, SOCKET_ID_ANY, &config);
if (NULL == lpm)
return -1;
diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index f367553..aaf95ec 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -105,6 +105,7 @@ rte_lpm_test tests[] = {
#define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0]))
#define MAX_DEPTH 32
#define MAX_RULES 256
+#define NUMBER_TBL8S 256
#define PASS 0
/*
@@ -115,18 +116,25 @@ int32_t
test0(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
/* rte_lpm_create: lpm name == NULL */
- lpm = rte_lpm_create(NULL, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(NULL, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm == NULL);
/* rte_lpm_create: max_rules = 0 */
/* Note: __func__ inserts the function name, in this case "test0". */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 0, 0);
+ config.max_rules = 0;
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm == NULL);
/* socket_id < -1 is invalid */
- lpm = rte_lpm_create(__func__, -2, MAX_RULES, 0);
+ config.max_rules = MAX_RULES;
+ lpm = rte_lpm_create(__func__, -2, &config);
TEST_LPM_ASSERT(lpm == NULL);
return PASS;
@@ -140,11 +148,16 @@ int32_t
test1(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
int32_t i;
/* rte_lpm_free: Free NULL */
for (i = 0; i < 100; i++) {
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES - i, 0);
+ config.max_rules = MAX_RULES - i;
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
rte_lpm_free(lpm);
@@ -164,8 +177,13 @@ int32_t
test2(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
rte_lpm_free(lpm);
@@ -180,6 +198,11 @@ int32_t
test3(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop = 100;
uint8_t depth = 24;
int32_t status = 0;
@@ -189,7 +212,7 @@ test3(void)
TEST_LPM_ASSERT(status < 0);
/*Create vaild lpm to use in rest of test. */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* rte_lpm_add: depth < 1 */
@@ -213,6 +236,11 @@ int32_t
test4(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0);
uint8_t depth = 24;
int32_t status = 0;
@@ -222,7 +250,7 @@ test4(void)
TEST_LPM_ASSERT(status < 0);
/*Create vaild lpm to use in rest of test. */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* rte_lpm_delete: depth < 1 */
@@ -247,6 +275,11 @@ test5(void)
{
#if defined(RTE_LIBRTE_LPM_DEBUG)
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop_return = 0;
int32_t status = 0;
@@ -255,7 +288,7 @@ test5(void)
TEST_LPM_ASSERT(status < 0);
/*Create vaild lpm to use in rest of test. */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* rte_lpm_lookup: depth < 1 */
@@ -276,11 +309,16 @@ int32_t
test6(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0;
uint8_t depth = 24;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
status = rte_lpm_add(lpm, ip, depth, next_hop_add);
@@ -310,11 +348,16 @@ test7(void)
__m128i ipx4;
uint32_t hop[4];
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0;
uint8_t depth = 32;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
status = rte_lpm_add(lpm, ip, depth, next_hop_add);
@@ -356,12 +399,17 @@ test8(void)
__m128i ipx4;
uint32_t hop[4];
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip1 = IPv4(127, 255, 255, 255), ip2 = IPv4(128, 0, 0, 0);
uint32_t next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* Loop with rte_lpm_add. */
@@ -436,6 +484,11 @@ int32_t
test9(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, ip_1, ip_2;
uint8_t depth, depth_1, depth_2;
uint32_t next_hop_add, next_hop_add_1, next_hop_add_2, next_hop_return;
@@ -446,7 +499,7 @@ test9(void)
depth = 24;
next_hop_add = 100;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
status = rte_lpm_add(lpm, ip, depth, next_hop_add);
@@ -600,13 +653,18 @@ test10(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
/* Add rule that covers a TBL24 range previously invalid & lookup
* (& delete & lookup) */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -786,11 +844,16 @@ test11(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -852,11 +915,16 @@ test12(void)
__m128i ipx4;
uint32_t hop[4];
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, i, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -902,11 +970,16 @@ int32_t
test13(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, i, next_hop_add_1, next_hop_add_2, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -964,12 +1037,17 @@ test14(void)
* that we have enough storage for all rules at that depth*/
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = 256 * 32;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
/* Add enough space for 256 rules for every depth */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 256 * 32, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
depth = 32;
@@ -1011,9 +1089,14 @@ int32_t
test15(void)
{
struct rte_lpm *lpm = NULL, *result = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = 256 * 32;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
/* Create lpm */
- lpm = rte_lpm_create("lpm_find_existing", SOCKET_ID_ANY, 256 * 32, 0);
+ lpm = rte_lpm_create("lpm_find_existing", SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* Try to find existing lpm */
@@ -1039,8 +1122,12 @@ int32_t
test16(void)
{
uint32_t ip;
- struct rte_lpm *lpm = rte_lpm_create(__func__, SOCKET_ID_ANY,
- 256 * 32, 0);
+ struct rte_lpm_config config;
+
+ config.max_rules = 256 * 32;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
+ struct rte_lpm *lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
/* ip loops through all possibilities for top 24 bits of address */
for (ip = 0; ip < 0xFFFFFF; ip++) {
@@ -1050,10 +1137,10 @@ test16(void)
break;
}
- if (ip != RTE_LPM_TBL8_NUM_GROUPS) {
+ if (ip != NUMBER_TBL8S) {
printf("Error, unexpected failure with filling tbl8 groups\n");
printf("Failed after %u additions, expected after %u\n",
- (unsigned)ip, (unsigned)RTE_LPM_TBL8_NUM_GROUPS);
+ (unsigned)ip, (unsigned)NUMBER_TBL8S);
}
rte_lpm_free(lpm);
@@ -1071,6 +1158,11 @@ int32_t
test17(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
const uint32_t ip_10_32 = IPv4(10, 10, 10, 2);
const uint32_t ip_10_24 = IPv4(10, 10, 10, 0);
const uint32_t ip_20_25 = IPv4(10, 10, 20, 2);
@@ -1083,7 +1175,7 @@ test17(void)
uint32_t next_hop_return = 0;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
if ((status = rte_lpm_add(lpm, ip_10_32, d_ip_10_32,
@@ -1172,6 +1264,11 @@ int32_t
perf_test(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = 1000000;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint64_t begin, total_time, lpm_used_entries = 0;
unsigned i, j;
uint32_t next_hop_add = 0xAA, next_hop_return = 0;
@@ -1185,7 +1282,7 @@ perf_test(void)
print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES);
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 1000000, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* Measue add. */
diff --git a/app/test/test_mp_secondary.c b/app/test/test_mp_secondary.c
index 2f941b5..4dfe418 100644
--- a/app/test/test_mp_secondary.c
+++ b/app/test/test_mp_secondary.c
@@ -232,7 +232,12 @@ run_object_creation_tests(void)
#ifdef RTE_LIBRTE_LPM
rte_errno=0;
- if ((rte_lpm_create("test_lpm", size, rte_socket_id(), 0) != NULL) &&
+ struct rte_lpm_config config;
+
+ config.max_rules = rte_socket_id();
+ config.number_tbl8s = 256;
+ config.flags = 0;
+ if ((rte_lpm_create("test_lpm", size, &config) != NULL) &&
(rte_lpm_find_existing("test_lpm") == NULL)){
printf("Error: unexpected return value from rte_lpm_create()\n");
return -1;
diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
index 8bf4aeb..acb4f4d 100644
--- a/app/test/test_table_combined.c
+++ b/app/test/test_table_combined.c
@@ -295,6 +295,8 @@ test_table_lpm_combined(void)
struct rte_table_lpm_params lpm_params = {
.name = "LPM",
.n_rules = 1 << 16,
+ .number_tbl8s = 1 << 8,
+ .flags = 0,
.entry_unique_size = 8,
.offset = APP_METADATA_OFFSET(0),
};
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
index b6364c4..cbbbfc1 100644
--- a/app/test/test_table_tables.c
+++ b/app/test/test_table_tables.c
@@ -326,6 +326,8 @@ test_table_lpm(void)
struct rte_table_lpm_params lpm_params = {
.name = "LPM",
.n_rules = 1 << 24,
+ .number_tbl8s = 1 << 8,
+ .flags = 0,
.entry_unique_size = entry_size,
.offset = APP_METADATA_OFFSET(1)
};
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 686db70..24f4079 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -102,6 +102,11 @@ Libraries
Extended next_hop field from 8-bits to 24-bits for IPv4.
+* **librte_lpm: Added a new rte_lpm_config structure for IPv4.**
+
+ A new rte_lpm_config structure is used so LPM library will allocate exactly
+ the amount of memory which is necessary to hold application’s rules.
+
Examples
~~~~~~~~
diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index ea4d234..ccaaa2a 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -244,13 +244,13 @@ exit:
VERSION_SYMBOL(rte_lpm_create, _v20, 2.0);
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
- __rte_unused int flags)
+rte_lpm_create_v1604(const char *name, int socket_id,
+ const struct rte_lpm_config *config)
{
char mem_name[RTE_LPM_NAMESIZE];
struct rte_lpm *lpm = NULL;
struct rte_tailq_entry *te;
- uint32_t mem_size;
+ uint32_t mem_size, rules_size, tbl8s_size;
struct rte_lpm_list *lpm_list;
lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
@@ -258,7 +258,8 @@ rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl_entry) != 4);
/* Check user arguments. */
- if ((name == NULL) || (socket_id < -1) || (max_rules == 0)) {
+ if ((name == NULL) || (socket_id < -1) || (config->max_rules == 0)
+ || config->number_tbl8s > RTE_LPM_MAX_TBL8_NUM_GROUPS) {
rte_errno = EINVAL;
return NULL;
}
@@ -266,7 +267,10 @@ rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
snprintf(mem_name, sizeof(mem_name), "LPM_%s", name);
/* Determine the amount of memory to allocate. */
- mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
+ mem_size = sizeof(*lpm);
+ rules_size = sizeof(struct rte_lpm_rule) * config->max_rules;
+ tbl8s_size = (sizeof(struct rte_lpm_tbl_entry) *
+ RTE_LPM_TBL8_GROUP_NUM_ENTRIES * config->number_tbl8s);
rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
@@ -295,8 +299,29 @@ rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
goto exit;
}
+ lpm->rules_tbl = (struct rte_lpm_rule *)rte_zmalloc_socket(NULL,
+ (size_t)rules_size, RTE_CACHE_LINE_SIZE, socket_id);
+
+ if (lpm->rules_tbl == NULL) {
+ RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
+ rte_free(lpm);
+ rte_free(te);
+ goto exit;
+ }
+
+ lpm->tbl8 = (struct rte_lpm_tbl_entry *)rte_zmalloc_socket(NULL,
+ (size_t)tbl8s_size, RTE_CACHE_LINE_SIZE, socket_id);
+
+ if (lpm->tbl8 == NULL) {
+ RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
+ rte_free(lpm);
+ rte_free(te);
+ goto exit;
+ }
+
/* Save user arguments. */
- lpm->max_rules = max_rules;
+ lpm->max_rules = config->max_rules;
+ lpm->number_tbl8s = config->number_tbl8s;
snprintf(lpm->name, sizeof(lpm->name), "%s", name);
te->data = (void *) lpm;
@@ -311,7 +336,7 @@ exit:
BIND_DEFAULT_SYMBOL(rte_lpm_create, _v1604, 16.04);
MAP_STATIC_SYMBOL(
struct rte_lpm *rte_lpm_create(const char *name, int socket_id,
- int max_rules, int flags), rte_lpm_create_v1604);
+ const struct rte_lpm_config *config), rte_lpm_create_v1604);
/*
* Deallocates memory for given LPM table.
@@ -665,14 +690,13 @@ tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20 *tbl8)
}
static inline int32_t
-tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8)
+tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
{
uint32_t group_idx; /* tbl8 group index. */
struct rte_lpm_tbl_entry *tbl8_entry;
/* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
- for (group_idx = 0; group_idx < RTE_LPM_TBL8_NUM_GROUPS;
- group_idx++) {
+ for (group_idx = 0; group_idx < number_tbl8s; group_idx++) {
tbl8_entry = &tbl8[group_idx * RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
/* If a free tbl8 group is found clean it and set as VALID. */
if (!tbl8_entry->valid_group) {
@@ -987,7 +1011,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
if (!lpm->tbl24[tbl24_index].valid) {
/* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8);
+ tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
/* Check tbl8 allocation was successful. */
if (tbl8_group_index < 0) {
@@ -1024,7 +1048,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
} /* If valid entry but not extended calculate the index into Table8. */
else if (lpm->tbl24[tbl24_index].valid_group == 0) {
/* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8);
+ tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
if (tbl8_group_index < 0) {
return tbl8_group_index;
@@ -1882,7 +1906,8 @@ rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
memset(lpm->tbl24, 0, sizeof(lpm->tbl24));
/* Zero tbl8. */
- memset(lpm->tbl8, 0, sizeof(lpm->tbl8));
+ memset(lpm->tbl8, 0, sizeof(lpm->tbl8[0])
+ * RTE_LPM_TBL8_GROUP_NUM_ENTRIES * lpm->number_tbl8s);
/* Delete all rules form the rules table. */
memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index d759c8a..9aa122c 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -66,6 +66,9 @@ extern "C" {
/** @internal Number of entries in a tbl8 group. */
#define RTE_LPM_TBL8_GROUP_NUM_ENTRIES 256
+/** @internal Max number of tbl8 groups in the tbl8. */
+#define RTE_LPM_MAX_TBL8_NUM_GROUPS (1 << 24)
+
/** @internal Total number of tbl8 groups in the tbl8. */
#define RTE_LPM_TBL8_NUM_GROUPS 256
@@ -154,6 +157,13 @@ struct rte_lpm_tbl_entry {
#endif
+/** LPM configuration structure. */
+struct rte_lpm_config {
+ uint32_t max_rules; /**< Max number of rules. */
+ uint32_t number_tbl8s; /**< Number of tbl8s to allocate. */
+ int flags; /**< This field is currently unused. */
+};
+
/** @internal Rule structure. */
struct rte_lpm_rule_v20 {
uint32_t ip; /**< Rule IP address. */
@@ -191,15 +201,14 @@ struct rte_lpm {
/* LPM metadata. */
char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
uint32_t max_rules; /**< Max. balanced rules per lpm. */
+ uint32_t number_tbl8s; /**< Number of tbl8s. */
struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
/* LPM Tables. */
struct rte_lpm_tbl_entry tbl24[RTE_LPM_TBL24_NUM_ENTRIES]
__rte_cache_aligned; /**< LPM tbl24 table. */
- struct rte_lpm_tbl_entry tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule rules_tbl[0] \
- __rte_cache_aligned; /**< LPM rules. */
+ struct rte_lpm_tbl_entry *tbl8; /**< LPM tbl8 table. */
+ struct rte_lpm_rule *rules_tbl; /**< LPM rules. */
};
/**
@@ -224,11 +233,13 @@ struct rte_lpm {
* - ENOMEM - no appropriate memory area found in which to create memzone
*/
struct rte_lpm *
-rte_lpm_create(const char *name, int socket_id, int max_rules, int flags);
+rte_lpm_create(const char *name, int socket_id,
+ const struct rte_lpm_config *config);
struct rte_lpm_v20 *
rte_lpm_create_v20(const char *name, int socket_id, int max_rules, int flags);
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id, int max_rules, int flags);
+rte_lpm_create_v1604(const char *name, int socket_id,
+ const struct rte_lpm_config *config);
/**
* Find an existing LPM object and return a pointer to it.
diff --git a/lib/librte_table/rte_table_lpm.c b/lib/librte_table/rte_table_lpm.c
index 7b2ecb0..cdeb0f5 100644
--- a/lib/librte_table/rte_table_lpm.c
+++ b/lib/librte_table/rte_table_lpm.c
@@ -82,6 +82,8 @@ rte_table_lpm_create(void *params, int socket_id, uint32_t entry_size)
{
struct rte_table_lpm_params *p = (struct rte_table_lpm_params *) params;
struct rte_table_lpm *lpm;
+ struct rte_lpm_config lpm_config;
+
uint32_t total_size, nht_size;
/* Check input parameters */
@@ -93,6 +95,10 @@ rte_table_lpm_create(void *params, int socket_id, uint32_t entry_size)
RTE_LOG(ERR, TABLE, "%s: Invalid n_rules\n", __func__);
return NULL;
}
+ if (p->number_tbl8s == 0) {
+ RTE_LOG(ERR, TABLE, "%s: Invalid number_tbl8s\n", __func__);
+ return NULL;
+ }
if (p->entry_unique_size == 0) {
RTE_LOG(ERR, TABLE, "%s: Invalid entry_unique_size\n",
__func__);
@@ -123,7 +129,11 @@ rte_table_lpm_create(void *params, int socket_id, uint32_t entry_size)
}
/* LPM low-level table creation */
- lpm->lpm = rte_lpm_create(p->name, socket_id, p->n_rules, 0);
+ lpm_config.max_rules = p->n_rules;
+ lpm_config.number_tbl8s = p->number_tbl8s;
+ lpm_config.flags = p->flags;
+ lpm->lpm = rte_lpm_create(p->name, socket_id, &lpm_config);
+
if (lpm->lpm == NULL) {
rte_free(lpm);
RTE_LOG(ERR, TABLE, "Unable to create low-level LPM table\n");
diff --git a/lib/librte_table/rte_table_lpm.h b/lib/librte_table/rte_table_lpm.h
index 06e8410..f303323 100644
--- a/lib/librte_table/rte_table_lpm.h
+++ b/lib/librte_table/rte_table_lpm.h
@@ -83,6 +83,12 @@ struct rte_table_lpm_params {
/** Maximum number of LPM rules (i.e. IP routes) */
uint32_t n_rules;
+ /**< Number of tbl8s to allocate. */
+ uint32_t number_tbl8s;
+
+ /**< This field is currently unused. */
+ int flags;
+
/** Number of bytes at the start of the table entry that uniquely
identify the entry. Cannot be bigger than table entry size. */
uint32_t entry_unique_size;
--
1.9.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH 2/2] examples: update to use new rte_lpm_config for ipv4
2016-03-08 20:57 [dpdk-dev] [PATCH 0/2] Added a new rte_lpm_config structure for IPv4 Michal Kobylinski
2016-03-08 20:57 ` [dpdk-dev] [PATCH 1/2] lpm: added a new rte_lpm_config structure for ipv4 Michal Kobylinski
@ 2016-03-08 20:57 ` Michal Kobylinski
2016-03-09 0:47 ` [dpdk-dev] [PATCH 0/2] Added a new rte_lpm_config structure for IPv4 Thomas Monjalon
2016-03-09 12:43 ` [dpdk-dev] [PATCH v2] lpm: added a new rte_lpm_config structure for ipv4 Michal Jastrzebski
3 siblings, 0 replies; 6+ messages in thread
From: Michal Kobylinski @ 2016-03-08 20:57 UTC (permalink / raw)
To: dev
Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
examples/ip_fragmentation/main.c | 7 ++++++-
examples/ip_reassembly/main.c | 7 ++++++-
examples/l3fwd-power/main.c | 10 ++++++++--
examples/l3fwd-vf/main.c | 10 ++++++++--
examples/l3fwd/l3fwd_lpm.c | 9 +++++++--
examples/load_balancer/init.c | 8 ++++++--
examples/performance-thread/l3fwd-thread/main.c | 8 ++++++--
7 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 0302b2c..8021702 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -721,6 +721,7 @@ init_mem(void)
struct rte_mempool *mp;
struct rte_lpm *lpm;
struct rte_lpm6 *lpm6;
+ struct rte_lpm_config lpm_config;
int socket;
unsigned lcore_id;
@@ -768,7 +769,11 @@ init_mem(void)
RTE_LOG(INFO, IP_FRAG, "Creating LPM table on socket %i\n", socket);
snprintf(buf, sizeof(buf), "IP_FRAG_LPM_%i", socket);
- lpm = rte_lpm_create(buf, socket, LPM_MAX_RULES, 0);
+ lpm_config.max_rules = LPM_MAX_RULES;
+ lpm_config.number_tbl8s = 256;
+ lpm_config.flags = 0;
+
+ lpm = rte_lpm_create(buf, socket, &lpm_config);
if (lpm == NULL) {
RTE_LOG(ERR, IP_FRAG, "Cannot create LPM table\n");
return -1;
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 6f48748..19ec46c 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -927,6 +927,7 @@ init_mem(void)
char buf[PATH_MAX];
struct rte_lpm *lpm;
struct rte_lpm6 *lpm6;
+ struct rte_lpm_config lpm_config;
int socket;
unsigned lcore_id;
@@ -946,7 +947,11 @@ init_mem(void)
RTE_LOG(INFO, IP_RSMBL, "Creating LPM table on socket %i\n", socket);
snprintf(buf, sizeof(buf), "IP_RSMBL_LPM_%i", socket);
- lpm = rte_lpm_create(buf, socket, LPM_MAX_RULES, 0);
+ lpm_config.max_rules = LPM_MAX_RULES;
+ lpm_config.number_tbl8s = 256;
+ lpm_config.flags = 0;
+
+ lpm = rte_lpm_create(buf, socket, &lpm_config);
if (lpm == NULL) {
RTE_LOG(ERR, IP_RSMBL, "Cannot create LPM table\n");
return -1;
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index a478583..f8a2f1b 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1430,9 +1430,15 @@ setup_lpm(int socketid)
char s[64];
/* create the LPM table */
+ struct rte_lpm_config lpm_ipv4_config;
+
+ lpm_ipv4_config.max_rules = IPV4_L3FWD_LPM_MAX_RULES;
+ lpm_ipv4_config.number_tbl8s = 256;
+ lpm_ipv4_config.flags = 0;
+
snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid);
- ipv4_l3fwd_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- IPV4_L3FWD_LPM_MAX_RULES, 0);
+ ipv4_l3fwd_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &lpm_ipv4_config);
if (ipv4_l3fwd_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE, "Unable to create the l3fwd LPM table"
" on socket %d\n", socketid);
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index 193c3ab..034c22a 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -869,10 +869,16 @@ setup_lpm(int socketid)
int ret;
char s[64];
+ struct rte_lpm_config lpm_ipv4_config;
+
+ lpm_ipv4_config.max_rules = L3FWD_LPM_MAX_RULES;
+ lpm_ipv4_config.number_tbl8s = 256;
+ lpm_ipv4_config.flags = 0;
+
/* create the LPM table */
snprintf(s, sizeof(s), "L3FWD_LPM_%d", socketid);
- l3fwd_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- L3FWD_LPM_MAX_RULES, 0);
+ l3fwd_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &lpm_ipv4_config);
if (l3fwd_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE, "Unable to create the l3fwd LPM table"
" on socket %d\n", socketid);
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index e0ed3c4..a354797 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -98,6 +98,7 @@ static struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = {
(sizeof(ipv6_l3fwd_lpm_route_array) / sizeof(ipv6_l3fwd_lpm_route_array[0]))
#define IPV4_L3FWD_LPM_MAX_RULES 1024
+#define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 << 8)
#define IPV6_L3FWD_LPM_MAX_RULES 1024
#define IPV6_L3FWD_LPM_NUMBER_TBL8S (1 << 16)
@@ -203,14 +204,18 @@ void
setup_lpm(const int socketid)
{
struct rte_lpm6_config config;
+ struct rte_lpm_config config_ipv4;
unsigned i;
int ret;
char s[64];
/* create the LPM table */
+ config_ipv4.max_rules = IPV4_L3FWD_LPM_MAX_RULES;
+ config_ipv4.number_tbl8s = IPV4_L3FWD_LPM_NUMBER_TBL8S;
+ config_ipv4.flags = 0;
snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid);
- ipv4_l3fwd_lpm_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- IPV4_L3FWD_LPM_MAX_RULES, 0);
+ ipv4_l3fwd_lpm_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &config_ipv4);
if (ipv4_l3fwd_lpm_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE,
"Unable to create the l3fwd LPM table on socket %d\n",
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index 5a56078..a96d778 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -160,13 +160,17 @@ app_init_lpm_tables(void)
continue;
}
+ struct rte_lpm_config lpm_config;
+
+ lpm_config.max_rules = APP_MAX_LPM_RULES;
+ lpm_config.number_tbl8s = 256;
+ lpm_config.flags = 0;
snprintf(name, sizeof(name), "lpm_table_%u", socket);
printf("Creating the LPM table for socket %u ...\n", socket);
app.lpm_tables[socket] = rte_lpm_create(
name,
socket,
- APP_MAX_LPM_RULES,
- 0);
+ &lpm_config);
if (app.lpm_tables[socket] == NULL) {
rte_panic("Unable to create LPM table on socket %u\n", socket);
}
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index f1381f2..e68f7cb 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3249,14 +3249,18 @@ static void
setup_lpm(int socketid)
{
struct rte_lpm6_config config;
+ struct rte_lpm_config lpm_ipv4_config;
unsigned i;
int ret;
char s[64];
/* create the LPM table */
snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid);
- ipv4_l3fwd_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- IPV4_L3FWD_LPM_MAX_RULES, 0);
+ lpm_ipv4_config.max_rules = IPV4_L3FWD_LPM_MAX_RULES;
+ lpm_ipv4_config.number_tbl8s = 256;
+ lpm_ipv4_config.flags = 0;
+ ipv4_l3fwd_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &lpm_ipv4_config);
if (ipv4_l3fwd_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE, "Unable to create the l3fwd LPM table"
" on socket %d\n", socketid);
--
1.9.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [dpdk-dev] [PATCH 0/2] Added a new rte_lpm_config structure for IPv4.
2016-03-08 20:57 [dpdk-dev] [PATCH 0/2] Added a new rte_lpm_config structure for IPv4 Michal Kobylinski
2016-03-08 20:57 ` [dpdk-dev] [PATCH 1/2] lpm: added a new rte_lpm_config structure for ipv4 Michal Kobylinski
2016-03-08 20:57 ` [dpdk-dev] [PATCH 2/2] examples: update to use new rte_lpm_config " Michal Kobylinski
@ 2016-03-09 0:47 ` Thomas Monjalon
2016-03-09 12:43 ` [dpdk-dev] [PATCH v2] lpm: added a new rte_lpm_config structure for ipv4 Michal Jastrzebski
3 siblings, 0 replies; 6+ messages in thread
From: Thomas Monjalon @ 2016-03-09 0:47 UTC (permalink / raw)
To: Michal Kobylinski; +Cc: dev
2016-03-08 21:57, Michal Kobylinski:
> A new rte_lpm_config structure is used so LPM library will allocate
> exactly the amount of memory which is necessary to hold application’s
> rules.
Does it depend on "Increased number of next hops for LPM IPv4"?
I guess one patch is based on the other in your tree.
> Michal Kobylinski (2):
> lpm: added a new rte_lpm_config structure for ipv4
> examples: update to use new rte_lpm_config structure for ipv4
Please keep in 1 patch to avoid breaking compilation of examples in between.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v2] lpm: added a new rte_lpm_config structure for ipv4
2016-03-08 20:57 [dpdk-dev] [PATCH 0/2] Added a new rte_lpm_config structure for IPv4 Michal Kobylinski
` (2 preceding siblings ...)
2016-03-09 0:47 ` [dpdk-dev] [PATCH 0/2] Added a new rte_lpm_config structure for IPv4 Thomas Monjalon
@ 2016-03-09 12:43 ` Michal Jastrzebski
2016-03-09 13:16 ` Thomas Monjalon
3 siblings, 1 reply; 6+ messages in thread
From: Michal Jastrzebski @ 2016-03-09 12:43 UTC (permalink / raw)
To: dev
From: Michal Kobylinski <michalx.kobylinski@intel.com>
This patch depends on: lpm: extended ipv4 next_hop field (v4).
A new rte_lpm_config structure is used so LPM library will allocate
exactly the amount of memory which is necessary to hold application’s
rules.
Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
app/test/test_func_reentrancy.c | 9 +-
app/test/test_lpm.c | 145 ++++++++++++++++++++----
app/test/test_mp_secondary.c | 7 +-
app/test/test_table_combined.c | 2 +
app/test/test_table_tables.c | 2 +
doc/guides/rel_notes/release_16_04.rst | 5 +
examples/ip_fragmentation/main.c | 7 +-
examples/ip_reassembly/main.c | 7 +-
examples/l3fwd-power/main.c | 10 +-
examples/l3fwd-vf/main.c | 10 +-
examples/l3fwd/l3fwd_lpm.c | 9 +-
examples/load_balancer/init.c | 8 +-
examples/performance-thread/l3fwd-thread/main.c | 8 +-
lib/librte_lpm/rte_lpm.c | 51 ++++++---
lib/librte_lpm/rte_lpm.h | 23 +++-
lib/librte_table/rte_table_lpm.c | 12 +-
lib/librte_table/rte_table_lpm.h | 6 +
17 files changed, 262 insertions(+), 59 deletions(-)
diff --git a/app/test/test_func_reentrancy.c b/app/test/test_func_reentrancy.c
index dbecc52..5d09296 100644
--- a/app/test/test_func_reentrancy.c
+++ b/app/test/test_func_reentrancy.c
@@ -359,6 +359,11 @@ lpm_create_free(__attribute__((unused)) void *arg)
{
unsigned lcore_self = rte_lcore_id();
struct rte_lpm *lpm;
+ struct rte_lpm_config config;
+
+ config.max_rules = 4;
+ config.number_tbl8s = 256;
+ config.flags = 0;
char lpm_name[MAX_STRING_SIZE];
int i;
@@ -366,7 +371,7 @@ lpm_create_free(__attribute__((unused)) void *arg)
/* create the same lpm simultaneously on all threads */
for (i = 0; i < MAX_ITER_TIMES; i++) {
- lpm = rte_lpm_create("fr_test_once", SOCKET_ID_ANY, 4, 0);
+ lpm = rte_lpm_create("fr_test_once", SOCKET_ID_ANY, &config);
if ((NULL == lpm) && (rte_lpm_find_existing("fr_test_once") == NULL))
return -1;
}
@@ -374,7 +379,7 @@ lpm_create_free(__attribute__((unused)) void *arg)
/* create mutiple fbk tables simultaneously */
for (i = 0; i < MAX_LPM_ITER_TIMES; i++) {
snprintf(lpm_name, sizeof(lpm_name), "fr_test_%d_%d", lcore_self, i);
- lpm = rte_lpm_create(lpm_name, SOCKET_ID_ANY, 4, 0);
+ lpm = rte_lpm_create(lpm_name, SOCKET_ID_ANY, &config);
if (NULL == lpm)
return -1;
diff --git a/app/test/test_lpm.c b/app/test/test_lpm.c
index f367553..aaf95ec 100644
--- a/app/test/test_lpm.c
+++ b/app/test/test_lpm.c
@@ -105,6 +105,7 @@ rte_lpm_test tests[] = {
#define NUM_LPM_TESTS (sizeof(tests)/sizeof(tests[0]))
#define MAX_DEPTH 32
#define MAX_RULES 256
+#define NUMBER_TBL8S 256
#define PASS 0
/*
@@ -115,18 +116,25 @@ int32_t
test0(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
/* rte_lpm_create: lpm name == NULL */
- lpm = rte_lpm_create(NULL, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(NULL, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm == NULL);
/* rte_lpm_create: max_rules = 0 */
/* Note: __func__ inserts the function name, in this case "test0". */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 0, 0);
+ config.max_rules = 0;
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm == NULL);
/* socket_id < -1 is invalid */
- lpm = rte_lpm_create(__func__, -2, MAX_RULES, 0);
+ config.max_rules = MAX_RULES;
+ lpm = rte_lpm_create(__func__, -2, &config);
TEST_LPM_ASSERT(lpm == NULL);
return PASS;
@@ -140,11 +148,16 @@ int32_t
test1(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
int32_t i;
/* rte_lpm_free: Free NULL */
for (i = 0; i < 100; i++) {
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES - i, 0);
+ config.max_rules = MAX_RULES - i;
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
rte_lpm_free(lpm);
@@ -164,8 +177,13 @@ int32_t
test2(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
rte_lpm_free(lpm);
@@ -180,6 +198,11 @@ int32_t
test3(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop = 100;
uint8_t depth = 24;
int32_t status = 0;
@@ -189,7 +212,7 @@ test3(void)
TEST_LPM_ASSERT(status < 0);
/*Create vaild lpm to use in rest of test. */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* rte_lpm_add: depth < 1 */
@@ -213,6 +236,11 @@ int32_t
test4(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0);
uint8_t depth = 24;
int32_t status = 0;
@@ -222,7 +250,7 @@ test4(void)
TEST_LPM_ASSERT(status < 0);
/*Create vaild lpm to use in rest of test. */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* rte_lpm_delete: depth < 1 */
@@ -247,6 +275,11 @@ test5(void)
{
#if defined(RTE_LIBRTE_LPM_DEBUG)
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop_return = 0;
int32_t status = 0;
@@ -255,7 +288,7 @@ test5(void)
TEST_LPM_ASSERT(status < 0);
/*Create vaild lpm to use in rest of test. */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* rte_lpm_lookup: depth < 1 */
@@ -276,11 +309,16 @@ int32_t
test6(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0;
uint8_t depth = 24;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
status = rte_lpm_add(lpm, ip, depth, next_hop_add);
@@ -310,11 +348,16 @@ test7(void)
__m128i ipx4;
uint32_t hop[4];
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip = IPv4(0, 0, 0, 0), next_hop_add = 100, next_hop_return = 0;
uint8_t depth = 32;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
status = rte_lpm_add(lpm, ip, depth, next_hop_add);
@@ -356,12 +399,17 @@ test8(void)
__m128i ipx4;
uint32_t hop[4];
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip1 = IPv4(127, 255, 255, 255), ip2 = IPv4(128, 0, 0, 0);
uint32_t next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* Loop with rte_lpm_add. */
@@ -436,6 +484,11 @@ int32_t
test9(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, ip_1, ip_2;
uint8_t depth, depth_1, depth_2;
uint32_t next_hop_add, next_hop_add_1, next_hop_add_2, next_hop_return;
@@ -446,7 +499,7 @@ test9(void)
depth = 24;
next_hop_add = 100;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
status = rte_lpm_add(lpm, ip, depth, next_hop_add);
@@ -600,13 +653,18 @@ test10(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
/* Add rule that covers a TBL24 range previously invalid & lookup
* (& delete & lookup) */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -786,11 +844,16 @@ test11(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -852,11 +915,16 @@ test12(void)
__m128i ipx4;
uint32_t hop[4];
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, i, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -902,11 +970,16 @@ int32_t
test13(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, i, next_hop_add_1, next_hop_add_2, next_hop_return;
uint8_t depth;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
ip = IPv4(128, 0, 0, 0);
@@ -964,12 +1037,17 @@ test14(void)
* that we have enough storage for all rules at that depth*/
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = 256 * 32;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint32_t ip, next_hop_add, next_hop_return;
uint8_t depth;
int32_t status = 0;
/* Add enough space for 256 rules for every depth */
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 256 * 32, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
depth = 32;
@@ -1011,9 +1089,14 @@ int32_t
test15(void)
{
struct rte_lpm *lpm = NULL, *result = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = 256 * 32;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
/* Create lpm */
- lpm = rte_lpm_create("lpm_find_existing", SOCKET_ID_ANY, 256 * 32, 0);
+ lpm = rte_lpm_create("lpm_find_existing", SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* Try to find existing lpm */
@@ -1039,8 +1122,12 @@ int32_t
test16(void)
{
uint32_t ip;
- struct rte_lpm *lpm = rte_lpm_create(__func__, SOCKET_ID_ANY,
- 256 * 32, 0);
+ struct rte_lpm_config config;
+
+ config.max_rules = 256 * 32;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
+ struct rte_lpm *lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
/* ip loops through all possibilities for top 24 bits of address */
for (ip = 0; ip < 0xFFFFFF; ip++) {
@@ -1050,10 +1137,10 @@ test16(void)
break;
}
- if (ip != RTE_LPM_TBL8_NUM_GROUPS) {
+ if (ip != NUMBER_TBL8S) {
printf("Error, unexpected failure with filling tbl8 groups\n");
printf("Failed after %u additions, expected after %u\n",
- (unsigned)ip, (unsigned)RTE_LPM_TBL8_NUM_GROUPS);
+ (unsigned)ip, (unsigned)NUMBER_TBL8S);
}
rte_lpm_free(lpm);
@@ -1071,6 +1158,11 @@ int32_t
test17(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = MAX_RULES;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
const uint32_t ip_10_32 = IPv4(10, 10, 10, 2);
const uint32_t ip_10_24 = IPv4(10, 10, 10, 0);
const uint32_t ip_20_25 = IPv4(10, 10, 20, 2);
@@ -1083,7 +1175,7 @@ test17(void)
uint32_t next_hop_return = 0;
int32_t status = 0;
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, MAX_RULES, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
if ((status = rte_lpm_add(lpm, ip_10_32, d_ip_10_32,
@@ -1172,6 +1264,11 @@ int32_t
perf_test(void)
{
struct rte_lpm *lpm = NULL;
+ struct rte_lpm_config config;
+
+ config.max_rules = 1000000;
+ config.number_tbl8s = NUMBER_TBL8S;
+ config.flags = 0;
uint64_t begin, total_time, lpm_used_entries = 0;
unsigned i, j;
uint32_t next_hop_add = 0xAA, next_hop_return = 0;
@@ -1185,7 +1282,7 @@ perf_test(void)
print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES);
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 1000000, 0);
+ lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config);
TEST_LPM_ASSERT(lpm != NULL);
/* Measue add. */
diff --git a/app/test/test_mp_secondary.c b/app/test/test_mp_secondary.c
index 2f941b5..4dfe418 100644
--- a/app/test/test_mp_secondary.c
+++ b/app/test/test_mp_secondary.c
@@ -232,7 +232,12 @@ run_object_creation_tests(void)
#ifdef RTE_LIBRTE_LPM
rte_errno=0;
- if ((rte_lpm_create("test_lpm", size, rte_socket_id(), 0) != NULL) &&
+ struct rte_lpm_config config;
+
+ config.max_rules = rte_socket_id();
+ config.number_tbl8s = 256;
+ config.flags = 0;
+ if ((rte_lpm_create("test_lpm", size, &config) != NULL) &&
(rte_lpm_find_existing("test_lpm") == NULL)){
printf("Error: unexpected return value from rte_lpm_create()\n");
return -1;
diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
index 8bf4aeb..acb4f4d 100644
--- a/app/test/test_table_combined.c
+++ b/app/test/test_table_combined.c
@@ -295,6 +295,8 @@ test_table_lpm_combined(void)
struct rte_table_lpm_params lpm_params = {
.name = "LPM",
.n_rules = 1 << 16,
+ .number_tbl8s = 1 << 8,
+ .flags = 0,
.entry_unique_size = 8,
.offset = APP_METADATA_OFFSET(0),
};
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
index b6364c4..cbbbfc1 100644
--- a/app/test/test_table_tables.c
+++ b/app/test/test_table_tables.c
@@ -326,6 +326,8 @@ test_table_lpm(void)
struct rte_table_lpm_params lpm_params = {
.name = "LPM",
.n_rules = 1 << 24,
+ .number_tbl8s = 1 << 8,
+ .flags = 0,
.entry_unique_size = entry_size,
.offset = APP_METADATA_OFFSET(1)
};
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 6f62dd8..79474ce 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -108,6 +108,11 @@ Libraries
Extended next_hop field from 8-bits to 24-bits for IPv4.
+* **librte_lpm: Added a new rte_lpm_config structure for IPv4.**
+
+ A new rte_lpm_config structure is used so LPM library will allocate exactly
+ the amount of memory which is necessary to hold application’s rules.
+
Examples
~~~~~~~~
diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c
index 0302b2c..8021702 100644
--- a/examples/ip_fragmentation/main.c
+++ b/examples/ip_fragmentation/main.c
@@ -721,6 +721,7 @@ init_mem(void)
struct rte_mempool *mp;
struct rte_lpm *lpm;
struct rte_lpm6 *lpm6;
+ struct rte_lpm_config lpm_config;
int socket;
unsigned lcore_id;
@@ -768,7 +769,11 @@ init_mem(void)
RTE_LOG(INFO, IP_FRAG, "Creating LPM table on socket %i\n", socket);
snprintf(buf, sizeof(buf), "IP_FRAG_LPM_%i", socket);
- lpm = rte_lpm_create(buf, socket, LPM_MAX_RULES, 0);
+ lpm_config.max_rules = LPM_MAX_RULES;
+ lpm_config.number_tbl8s = 256;
+ lpm_config.flags = 0;
+
+ lpm = rte_lpm_create(buf, socket, &lpm_config);
if (lpm == NULL) {
RTE_LOG(ERR, IP_FRAG, "Cannot create LPM table\n");
return -1;
diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c
index 6f48748..19ec46c 100644
--- a/examples/ip_reassembly/main.c
+++ b/examples/ip_reassembly/main.c
@@ -927,6 +927,7 @@ init_mem(void)
char buf[PATH_MAX];
struct rte_lpm *lpm;
struct rte_lpm6 *lpm6;
+ struct rte_lpm_config lpm_config;
int socket;
unsigned lcore_id;
@@ -946,7 +947,11 @@ init_mem(void)
RTE_LOG(INFO, IP_RSMBL, "Creating LPM table on socket %i\n", socket);
snprintf(buf, sizeof(buf), "IP_RSMBL_LPM_%i", socket);
- lpm = rte_lpm_create(buf, socket, LPM_MAX_RULES, 0);
+ lpm_config.max_rules = LPM_MAX_RULES;
+ lpm_config.number_tbl8s = 256;
+ lpm_config.flags = 0;
+
+ lpm = rte_lpm_create(buf, socket, &lpm_config);
if (lpm == NULL) {
RTE_LOG(ERR, IP_RSMBL, "Cannot create LPM table\n");
return -1;
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index a478583..f8a2f1b 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1430,9 +1430,15 @@ setup_lpm(int socketid)
char s[64];
/* create the LPM table */
+ struct rte_lpm_config lpm_ipv4_config;
+
+ lpm_ipv4_config.max_rules = IPV4_L3FWD_LPM_MAX_RULES;
+ lpm_ipv4_config.number_tbl8s = 256;
+ lpm_ipv4_config.flags = 0;
+
snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid);
- ipv4_l3fwd_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- IPV4_L3FWD_LPM_MAX_RULES, 0);
+ ipv4_l3fwd_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &lpm_ipv4_config);
if (ipv4_l3fwd_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE, "Unable to create the l3fwd LPM table"
" on socket %d\n", socketid);
diff --git a/examples/l3fwd-vf/main.c b/examples/l3fwd-vf/main.c
index 193c3ab..034c22a 100644
--- a/examples/l3fwd-vf/main.c
+++ b/examples/l3fwd-vf/main.c
@@ -869,10 +869,16 @@ setup_lpm(int socketid)
int ret;
char s[64];
+ struct rte_lpm_config lpm_ipv4_config;
+
+ lpm_ipv4_config.max_rules = L3FWD_LPM_MAX_RULES;
+ lpm_ipv4_config.number_tbl8s = 256;
+ lpm_ipv4_config.flags = 0;
+
/* create the LPM table */
snprintf(s, sizeof(s), "L3FWD_LPM_%d", socketid);
- l3fwd_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- L3FWD_LPM_MAX_RULES, 0);
+ l3fwd_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &lpm_ipv4_config);
if (l3fwd_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE, "Unable to create the l3fwd LPM table"
" on socket %d\n", socketid);
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index e0ed3c4..a354797 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -98,6 +98,7 @@ static struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = {
(sizeof(ipv6_l3fwd_lpm_route_array) / sizeof(ipv6_l3fwd_lpm_route_array[0]))
#define IPV4_L3FWD_LPM_MAX_RULES 1024
+#define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 << 8)
#define IPV6_L3FWD_LPM_MAX_RULES 1024
#define IPV6_L3FWD_LPM_NUMBER_TBL8S (1 << 16)
@@ -203,14 +204,18 @@ void
setup_lpm(const int socketid)
{
struct rte_lpm6_config config;
+ struct rte_lpm_config config_ipv4;
unsigned i;
int ret;
char s[64];
/* create the LPM table */
+ config_ipv4.max_rules = IPV4_L3FWD_LPM_MAX_RULES;
+ config_ipv4.number_tbl8s = IPV4_L3FWD_LPM_NUMBER_TBL8S;
+ config_ipv4.flags = 0;
snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid);
- ipv4_l3fwd_lpm_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- IPV4_L3FWD_LPM_MAX_RULES, 0);
+ ipv4_l3fwd_lpm_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &config_ipv4);
if (ipv4_l3fwd_lpm_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE,
"Unable to create the l3fwd LPM table on socket %d\n",
diff --git a/examples/load_balancer/init.c b/examples/load_balancer/init.c
index 5a56078..a96d778 100644
--- a/examples/load_balancer/init.c
+++ b/examples/load_balancer/init.c
@@ -160,13 +160,17 @@ app_init_lpm_tables(void)
continue;
}
+ struct rte_lpm_config lpm_config;
+
+ lpm_config.max_rules = APP_MAX_LPM_RULES;
+ lpm_config.number_tbl8s = 256;
+ lpm_config.flags = 0;
snprintf(name, sizeof(name), "lpm_table_%u", socket);
printf("Creating the LPM table for socket %u ...\n", socket);
app.lpm_tables[socket] = rte_lpm_create(
name,
socket,
- APP_MAX_LPM_RULES,
- 0);
+ &lpm_config);
if (app.lpm_tables[socket] == NULL) {
rte_panic("Unable to create LPM table on socket %u\n", socket);
}
diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c
index 59b7678..7bcca37 100644
--- a/examples/performance-thread/l3fwd-thread/main.c
+++ b/examples/performance-thread/l3fwd-thread/main.c
@@ -3249,14 +3249,18 @@ static void
setup_lpm(int socketid)
{
struct rte_lpm6_config config;
+ struct rte_lpm_config lpm_ipv4_config;
unsigned i;
int ret;
char s[64];
/* create the LPM table */
snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid);
- ipv4_l3fwd_lookup_struct[socketid] = rte_lpm_create(s, socketid,
- IPV4_L3FWD_LPM_MAX_RULES, 0);
+ lpm_ipv4_config.max_rules = IPV4_L3FWD_LPM_MAX_RULES;
+ lpm_ipv4_config.number_tbl8s = 256;
+ lpm_ipv4_config.flags = 0;
+ ipv4_l3fwd_lookup_struct[socketid] =
+ rte_lpm_create(s, socketid, &lpm_ipv4_config);
if (ipv4_l3fwd_lookup_struct[socketid] == NULL)
rte_exit(EXIT_FAILURE, "Unable to create the l3fwd LPM table"
" on socket %d\n", socketid);
diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index ea4d234..ccaaa2a 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -244,13 +244,13 @@ exit:
VERSION_SYMBOL(rte_lpm_create, _v20, 2.0);
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
- __rte_unused int flags)
+rte_lpm_create_v1604(const char *name, int socket_id,
+ const struct rte_lpm_config *config)
{
char mem_name[RTE_LPM_NAMESIZE];
struct rte_lpm *lpm = NULL;
struct rte_tailq_entry *te;
- uint32_t mem_size;
+ uint32_t mem_size, rules_size, tbl8s_size;
struct rte_lpm_list *lpm_list;
lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
@@ -258,7 +258,8 @@ rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl_entry) != 4);
/* Check user arguments. */
- if ((name == NULL) || (socket_id < -1) || (max_rules == 0)) {
+ if ((name == NULL) || (socket_id < -1) || (config->max_rules == 0)
+ || config->number_tbl8s > RTE_LPM_MAX_TBL8_NUM_GROUPS) {
rte_errno = EINVAL;
return NULL;
}
@@ -266,7 +267,10 @@ rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
snprintf(mem_name, sizeof(mem_name), "LPM_%s", name);
/* Determine the amount of memory to allocate. */
- mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
+ mem_size = sizeof(*lpm);
+ rules_size = sizeof(struct rte_lpm_rule) * config->max_rules;
+ tbl8s_size = (sizeof(struct rte_lpm_tbl_entry) *
+ RTE_LPM_TBL8_GROUP_NUM_ENTRIES * config->number_tbl8s);
rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
@@ -295,8 +299,29 @@ rte_lpm_create_v1604(const char *name, int socket_id, int max_rules,
goto exit;
}
+ lpm->rules_tbl = (struct rte_lpm_rule *)rte_zmalloc_socket(NULL,
+ (size_t)rules_size, RTE_CACHE_LINE_SIZE, socket_id);
+
+ if (lpm->rules_tbl == NULL) {
+ RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
+ rte_free(lpm);
+ rte_free(te);
+ goto exit;
+ }
+
+ lpm->tbl8 = (struct rte_lpm_tbl_entry *)rte_zmalloc_socket(NULL,
+ (size_t)tbl8s_size, RTE_CACHE_LINE_SIZE, socket_id);
+
+ if (lpm->tbl8 == NULL) {
+ RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
+ rte_free(lpm);
+ rte_free(te);
+ goto exit;
+ }
+
/* Save user arguments. */
- lpm->max_rules = max_rules;
+ lpm->max_rules = config->max_rules;
+ lpm->number_tbl8s = config->number_tbl8s;
snprintf(lpm->name, sizeof(lpm->name), "%s", name);
te->data = (void *) lpm;
@@ -311,7 +336,7 @@ exit:
BIND_DEFAULT_SYMBOL(rte_lpm_create, _v1604, 16.04);
MAP_STATIC_SYMBOL(
struct rte_lpm *rte_lpm_create(const char *name, int socket_id,
- int max_rules, int flags), rte_lpm_create_v1604);
+ const struct rte_lpm_config *config), rte_lpm_create_v1604);
/*
* Deallocates memory for given LPM table.
@@ -665,14 +690,13 @@ tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20 *tbl8)
}
static inline int32_t
-tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8)
+tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
{
uint32_t group_idx; /* tbl8 group index. */
struct rte_lpm_tbl_entry *tbl8_entry;
/* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
- for (group_idx = 0; group_idx < RTE_LPM_TBL8_NUM_GROUPS;
- group_idx++) {
+ for (group_idx = 0; group_idx < number_tbl8s; group_idx++) {
tbl8_entry = &tbl8[group_idx * RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
/* If a free tbl8 group is found clean it and set as VALID. */
if (!tbl8_entry->valid_group) {
@@ -987,7 +1011,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
if (!lpm->tbl24[tbl24_index].valid) {
/* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8);
+ tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
/* Check tbl8 allocation was successful. */
if (tbl8_group_index < 0) {
@@ -1024,7 +1048,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
} /* If valid entry but not extended calculate the index into Table8. */
else if (lpm->tbl24[tbl24_index].valid_group == 0) {
/* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8);
+ tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
if (tbl8_group_index < 0) {
return tbl8_group_index;
@@ -1882,7 +1906,8 @@ rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
memset(lpm->tbl24, 0, sizeof(lpm->tbl24));
/* Zero tbl8. */
- memset(lpm->tbl8, 0, sizeof(lpm->tbl8));
+ memset(lpm->tbl8, 0, sizeof(lpm->tbl8[0])
+ * RTE_LPM_TBL8_GROUP_NUM_ENTRIES * lpm->number_tbl8s);
/* Delete all rules form the rules table. */
memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index d759c8a..9aa122c 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -66,6 +66,9 @@ extern "C" {
/** @internal Number of entries in a tbl8 group. */
#define RTE_LPM_TBL8_GROUP_NUM_ENTRIES 256
+/** @internal Max number of tbl8 groups in the tbl8. */
+#define RTE_LPM_MAX_TBL8_NUM_GROUPS (1 << 24)
+
/** @internal Total number of tbl8 groups in the tbl8. */
#define RTE_LPM_TBL8_NUM_GROUPS 256
@@ -154,6 +157,13 @@ struct rte_lpm_tbl_entry {
#endif
+/** LPM configuration structure. */
+struct rte_lpm_config {
+ uint32_t max_rules; /**< Max number of rules. */
+ uint32_t number_tbl8s; /**< Number of tbl8s to allocate. */
+ int flags; /**< This field is currently unused. */
+};
+
/** @internal Rule structure. */
struct rte_lpm_rule_v20 {
uint32_t ip; /**< Rule IP address. */
@@ -191,15 +201,14 @@ struct rte_lpm {
/* LPM metadata. */
char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
uint32_t max_rules; /**< Max. balanced rules per lpm. */
+ uint32_t number_tbl8s; /**< Number of tbl8s. */
struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
/* LPM Tables. */
struct rte_lpm_tbl_entry tbl24[RTE_LPM_TBL24_NUM_ENTRIES]
__rte_cache_aligned; /**< LPM tbl24 table. */
- struct rte_lpm_tbl_entry tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule rules_tbl[0] \
- __rte_cache_aligned; /**< LPM rules. */
+ struct rte_lpm_tbl_entry *tbl8; /**< LPM tbl8 table. */
+ struct rte_lpm_rule *rules_tbl; /**< LPM rules. */
};
/**
@@ -224,11 +233,13 @@ struct rte_lpm {
* - ENOMEM - no appropriate memory area found in which to create memzone
*/
struct rte_lpm *
-rte_lpm_create(const char *name, int socket_id, int max_rules, int flags);
+rte_lpm_create(const char *name, int socket_id,
+ const struct rte_lpm_config *config);
struct rte_lpm_v20 *
rte_lpm_create_v20(const char *name, int socket_id, int max_rules, int flags);
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id, int max_rules, int flags);
+rte_lpm_create_v1604(const char *name, int socket_id,
+ const struct rte_lpm_config *config);
/**
* Find an existing LPM object and return a pointer to it.
diff --git a/lib/librte_table/rte_table_lpm.c b/lib/librte_table/rte_table_lpm.c
index 7b2ecb0..cdeb0f5 100644
--- a/lib/librte_table/rte_table_lpm.c
+++ b/lib/librte_table/rte_table_lpm.c
@@ -82,6 +82,8 @@ rte_table_lpm_create(void *params, int socket_id, uint32_t entry_size)
{
struct rte_table_lpm_params *p = (struct rte_table_lpm_params *) params;
struct rte_table_lpm *lpm;
+ struct rte_lpm_config lpm_config;
+
uint32_t total_size, nht_size;
/* Check input parameters */
@@ -93,6 +95,10 @@ rte_table_lpm_create(void *params, int socket_id, uint32_t entry_size)
RTE_LOG(ERR, TABLE, "%s: Invalid n_rules\n", __func__);
return NULL;
}
+ if (p->number_tbl8s == 0) {
+ RTE_LOG(ERR, TABLE, "%s: Invalid number_tbl8s\n", __func__);
+ return NULL;
+ }
if (p->entry_unique_size == 0) {
RTE_LOG(ERR, TABLE, "%s: Invalid entry_unique_size\n",
__func__);
@@ -123,7 +129,11 @@ rte_table_lpm_create(void *params, int socket_id, uint32_t entry_size)
}
/* LPM low-level table creation */
- lpm->lpm = rte_lpm_create(p->name, socket_id, p->n_rules, 0);
+ lpm_config.max_rules = p->n_rules;
+ lpm_config.number_tbl8s = p->number_tbl8s;
+ lpm_config.flags = p->flags;
+ lpm->lpm = rte_lpm_create(p->name, socket_id, &lpm_config);
+
if (lpm->lpm == NULL) {
rte_free(lpm);
RTE_LOG(ERR, TABLE, "Unable to create low-level LPM table\n");
diff --git a/lib/librte_table/rte_table_lpm.h b/lib/librte_table/rte_table_lpm.h
index 06e8410..f303323 100644
--- a/lib/librte_table/rte_table_lpm.h
+++ b/lib/librte_table/rte_table_lpm.h
@@ -83,6 +83,12 @@ struct rte_table_lpm_params {
/** Maximum number of LPM rules (i.e. IP routes) */
uint32_t n_rules;
+ /**< Number of tbl8s to allocate. */
+ uint32_t number_tbl8s;
+
+ /**< This field is currently unused. */
+ int flags;
+
/** Number of bytes at the start of the table entry that uniquely
identify the entry. Cannot be bigger than table entry size. */
uint32_t entry_unique_size;
--
1.9.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [dpdk-dev] [PATCH v2] lpm: added a new rte_lpm_config structure for ipv4
2016-03-09 12:43 ` [dpdk-dev] [PATCH v2] lpm: added a new rte_lpm_config structure for ipv4 Michal Jastrzebski
@ 2016-03-09 13:16 ` Thomas Monjalon
0 siblings, 0 replies; 6+ messages in thread
From: Thomas Monjalon @ 2016-03-09 13:16 UTC (permalink / raw)
To: Michal Jastrzebski; +Cc: dev
2016-03-09 13:43, Michal Jastrzebski:
> From: Michal Kobylinski <michalx.kobylinski@intel.com>
> struct rte_lpm *
> -rte_lpm_create(const char *name, int socket_id, int max_rules, int flags);
> +rte_lpm_create(const char *name, int socket_id,
> + const struct rte_lpm_config *config);
The doxygen comment must be updated:
rte_lpm.h:215: warning: argument 'max_rules' of command @param is not found
in the argument list
rte_lpm.h:215: warning: argument 'flags' of command @param is not found
in the argument list
rte_lpm.h:236: warning: The following parameters are not documented:
parameter 'config'
^ permalink raw reply [flat|nested] 6+ messages in thread