X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_lpm%2Frte_lpm.c;h=978ac6013ecf39aeb29aee368d7c1f83af8f9fab;hb=cefaee2de054db67e8a373f7b61a19600d67093b;hp=ea4d234deee7b38d4731adb32191d0be3f75896c;hpb=dc81ebbacaeb87d9dab302576ab676564c78557e;p=dpdk.git diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c index ea4d234dee..978ac6013e 100644 --- a/lib/librte_lpm/rte_lpm.c +++ b/lib/librte_lpm/rte_lpm.c @@ -209,8 +209,11 @@ rte_lpm_create_v20(const char *name, int socket_id, int max_rules, if (strncmp(name, lpm->name, RTE_LPM_NAMESIZE) == 0) break; } - if (te != NULL) + lpm = NULL; + if (te != NULL) { + rte_errno = EEXIST; goto exit; + } /* allocate tailq entry */ te = rte_zmalloc("LPM_TAILQ_ENTRY", sizeof(*te), 0); @@ -244,13 +247,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 +261,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 +270,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); @@ -276,8 +283,11 @@ rte_lpm_create_v1604(const char *name, int socket_id, int max_rules, if (strncmp(name, lpm->name, RTE_LPM_NAMESIZE) == 0) break; } - if (te != NULL) + lpm = NULL; + if (te != NULL) { + rte_errno = EEXIST; goto exit; + } /* allocate tailq entry */ te = rte_zmalloc("LPM_TAILQ_ENTRY", sizeof(*te), 0); @@ -295,8 +305,32 @@ 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 rules_tbl memory allocation failed\n"); + rte_free(lpm); + lpm = NULL; + 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 tbl8 memory allocation failed\n"); + rte_free(lpm->rules_tbl); + rte_free(lpm); + lpm = NULL; + 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 +345,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. @@ -335,12 +369,8 @@ rte_lpm_free_v20(struct rte_lpm_v20 *lpm) if (te->data == (void *) lpm) break; } - if (te == NULL) { - rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); - return; - } - - TAILQ_REMOVE(lpm_list, te, next); + if (te != NULL) + TAILQ_REMOVE(lpm_list, te, next); rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); @@ -368,15 +398,13 @@ rte_lpm_free_v1604(struct rte_lpm *lpm) if (te->data == (void *) lpm) break; } - if (te == NULL) { - rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); - return; - } - - TAILQ_REMOVE(lpm_list, te, next); + if (te != NULL) + TAILQ_REMOVE(lpm_list, te, next); rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); + rte_free(lpm->tbl8); + rte_free(lpm->rules_tbl); rte_free(lpm); rte_free(te); } @@ -665,14 +693,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) { @@ -724,11 +751,11 @@ add_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth, lpm->tbl24[i].depth <= depth)) { struct rte_lpm_tbl_entry_v20 new_tbl24_entry = { - { .next_hop = next_hop, }, .valid = VALID, .valid_group = 0, .depth = depth, }; + new_tbl24_entry.next_hop = next_hop; /* Setting tbl24 entry in one go to avoid race * conditions @@ -755,8 +782,8 @@ add_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth, .valid = VALID, .valid_group = VALID, .depth = depth, - .next_hop = next_hop, }; + new_tbl8_entry.next_hop = next_hop; /* * Setting tbl8 entry in one go to avoid @@ -915,14 +942,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; } /* @@ -955,10 +977,9 @@ add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth, struct rte_lpm_tbl_entry_v20 new_tbl8_entry = { .valid = VALID, .depth = depth, - .next_hop = next_hop, .valid_group = lpm->tbl8[i].valid_group, }; - + new_tbl8_entry.next_hop = next_hop; /* * Setting tbl8 entry in one go to avoid race * condition @@ -987,7 +1008,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) { @@ -1013,7 +1034,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth, */ struct rte_lpm_tbl_entry new_tbl24_entry = { - .group_idx = (uint8_t)tbl8_group_index, + .group_idx = tbl8_group_index, .valid = VALID, .valid_group = 1, .depth = 0, @@ -1024,7 +1045,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; @@ -1047,14 +1068,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; } /* @@ -1064,7 +1080,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth, */ struct rte_lpm_tbl_entry new_tbl24_entry = { - .group_idx = (uint8_t)tbl8_group_index, + .group_idx = tbl8_group_index, .valid = VALID, .valid_group = 1, .depth = 0, @@ -1355,9 +1371,9 @@ delete_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, .valid = VALID, .valid_group = VALID, .depth = sub_rule_depth, - .next_hop = lpm->rules_tbl - [sub_rule_index].next_hop, }; + new_tbl8_entry.next_hop = + lpm->rules_tbl[sub_rule_index].next_hop; for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) { @@ -1509,7 +1525,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++) { @@ -1556,7 +1572,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++) { @@ -1619,9 +1635,10 @@ delete_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, .valid = VALID, .depth = sub_rule_depth, .valid_group = lpm->tbl8[tbl8_group_start].valid_group, - .next_hop = lpm->rules_tbl[sub_rule_index].next_hop, }; + new_tbl8_entry.next_hop = + lpm->rules_tbl[sub_rule_index].next_hop; /* * Loop through the range of entries on tbl8 for which the * rule_to_delete must be modified. @@ -1882,7 +1899,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);