From: Michal Kobylinski <michalx.kobylinski@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 1/2] lpm: added a new rte_lpm_config structure for ipv4
Date: Tue, 8 Mar 2016 21:57:27 +0100 [thread overview]
Message-ID: <1457470648-26415-2-git-send-email-michalx.kobylinski@intel.com> (raw)
In-Reply-To: <1457470648-26415-1-git-send-email-michalx.kobylinski@intel.com>
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
next prev parent reply other threads:[~2016-03-08 20:56 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2016-03-08 20:57 ` [dpdk-dev] [PATCH 2/2] examples: update to use new rte_lpm_config for ipv4 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
2016-03-09 13:16 ` Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1457470648-26415-2-git-send-email-michalx.kobylinski@intel.com \
--to=michalx.kobylinski@intel.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).