X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_lpm%2Frte_lpm.c;h=0945b8103c262f73983d13f7cc030bd8e8761273;hb=a2348166ea186506d45b61d5073d16ad974e79bb;hp=35209c3301c278a7466d7758f319216f97e45476;hpb=212841e67cbc08c88fc9fcf0fc247859da5bc9ef;p=dpdk.git diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c index 35209c3301..0945b8103c 100644 --- a/lib/librte_lpm/rte_lpm.c +++ b/lib/librte_lpm/rte_lpm.c @@ -42,10 +42,9 @@ #include #include #include -#include /* for definition of CACHE_LINE_SIZE */ +#include /* for definition of RTE_CACHE_LINE_SIZE */ #include #include -#include #include #include #include @@ -56,7 +55,12 @@ #include "rte_lpm.h" -TAILQ_HEAD(rte_lpm_list, rte_lpm); +TAILQ_HEAD(rte_lpm_list, rte_tailq_entry); + +static struct rte_tailq_elem rte_lpm_tailq = { + .name = "RTE_LPM", +}; +EAL_REGISTER_TAILQ(rte_lpm_tailq) #define MAX_DEPTH_TBL24 24 @@ -118,24 +122,24 @@ depth_to_range(uint8_t depth) struct rte_lpm * rte_lpm_find_existing(const char *name) { - struct rte_lpm *l; + struct rte_lpm *l = NULL; + struct rte_tailq_entry *te; struct rte_lpm_list *lpm_list; - /* check that we have an initialised tail queue */ - if ((lpm_list = RTE_TAILQ_LOOKUP_BY_IDX(RTE_TAILQ_LPM, rte_lpm_list)) == NULL) { - rte_errno = E_RTE_NO_TAILQ; - return NULL; - } + lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list); rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK); - TAILQ_FOREACH(l, lpm_list, next) { + TAILQ_FOREACH(te, lpm_list, next) { + l = (struct rte_lpm *) te->data; if (strncmp(name, l->name, RTE_LPM_NAMESIZE) == 0) break; } rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK); - if (l == NULL) + if (te == NULL) { rte_errno = ENOENT; + return NULL; + } return l; } @@ -149,15 +153,11 @@ rte_lpm_create(const char *name, int socket_id, int max_rules, { char mem_name[RTE_LPM_NAMESIZE]; struct rte_lpm *lpm = NULL; + struct rte_tailq_entry *te; uint32_t mem_size; struct rte_lpm_list *lpm_list; - /* check that we have an initialised tail queue */ - if ((lpm_list = - RTE_TAILQ_LOOKUP_BY_IDX(RTE_TAILQ_LPM, rte_lpm_list)) == NULL) { - rte_errno = E_RTE_NO_TAILQ; - return NULL; - } + lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list); RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl24_entry) != 2); RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl8_entry) != 2); @@ -168,7 +168,7 @@ rte_lpm_create(const char *name, int socket_id, int max_rules, return NULL; } - rte_snprintf(mem_name, sizeof(mem_name), "LPM_%s", name); + 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); @@ -176,26 +176,37 @@ rte_lpm_create(const char *name, int socket_id, int max_rules, rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); /* guarantee there's no existing */ - TAILQ_FOREACH(lpm, lpm_list, next) { + TAILQ_FOREACH(te, lpm_list, next) { + lpm = (struct rte_lpm *) te->data; if (strncmp(name, lpm->name, RTE_LPM_NAMESIZE) == 0) break; } - if (lpm != NULL) + if (te != NULL) goto exit; + /* allocate tailq entry */ + te = rte_zmalloc("LPM_TAILQ_ENTRY", sizeof(*te), 0); + if (te == NULL) { + RTE_LOG(ERR, LPM, "Failed to allocate tailq entry\n"); + goto exit; + } + /* Allocate memory to store the LPM data structures. */ lpm = (struct rte_lpm *)rte_zmalloc_socket(mem_name, mem_size, - CACHE_LINE_SIZE, socket_id); + RTE_CACHE_LINE_SIZE, socket_id); if (lpm == NULL) { RTE_LOG(ERR, LPM, "LPM memory allocation failed\n"); + rte_free(te); goto exit; } /* Save user arguments. */ lpm->max_rules = max_rules; - rte_snprintf(lpm->name, sizeof(lpm->name), "%s", name); + snprintf(lpm->name, sizeof(lpm->name), "%s", name); + + te->data = (void *) lpm; - TAILQ_INSERT_TAIL(lpm_list, lpm, next); + TAILQ_INSERT_TAIL(lpm_list, te, next); exit: rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); @@ -209,12 +220,33 @@ exit: void rte_lpm_free(struct rte_lpm *lpm) { + struct rte_lpm_list *lpm_list; + struct rte_tailq_entry *te; + /* Check user arguments. */ if (lpm == NULL) return; - RTE_EAL_TAILQ_REMOVE(RTE_TAILQ_LPM, rte_lpm_list, lpm); + lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list); + + rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); + + /* find our tailq entry */ + TAILQ_FOREACH(te, lpm_list, next) { + if (te->data == (void *) lpm) + break; + } + if (te == NULL) { + rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); + return; + } + + TAILQ_REMOVE(lpm_list, te, next); + + rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); + rte_free(lpm); + rte_free(te); } /* @@ -255,6 +287,9 @@ rule_add(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth, return rule_index; } } + + if (rule_index == lpm->max_rules) + return -ENOSPC; } else { /* Calculate the position in which the rule will be stored. */ rule_index = 0; @@ -339,8 +374,8 @@ rule_find(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth) return (rule_index); } - /* If rule is not found return -E_RTE_NO_TAILQ. */ - return -E_RTE_NO_TAILQ; + /* If rule is not found return -EINVAL. */ + return -EINVAL; } /* @@ -924,10 +959,10 @@ rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth) /* * Check if rule_to_delete_index was found. If no rule was found the - * function rule_find returns -E_RTE_NO_TAILQ. + * function rule_find returns -EINVAL. */ if (rule_to_delete_index < 0) - return -E_RTE_NO_TAILQ; + return -EINVAL; /* Delete the rule from the rule table. */ rule_delete(lpm, rule_to_delete_index, depth);