To avoid a race condition while creating a new hash object, the list has to be locked before the lookup, and released only once the new object is added in the list.
Signed-off-by: Olivier Matz <olivier.matz at 6wind.com> --- lib/librte_hash/rte_cuckoo_hash.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c index ccec2db..18351fa 100644 --- a/lib/librte_hash/rte_cuckoo_hash.c +++ b/lib/librte_hash/rte_cuckoo_hash.c @@ -228,11 +228,17 @@ rte_hash_create(const struct rte_hash_parameters *params) snprintf(hash_name, sizeof(hash_name), "HT_%s", params->name); - /* Guarantee there's no existing */ - h = rte_hash_find_existing(params->name); - if (h != NULL) { + rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); + + /* guarantee there's no existing */ + TAILQ_FOREACH(te, hash_list, next) { + h = (struct rte_hash *) te->data; + if (strncmp(name, h->name, RTE_HASH_NAMESIZE) == 0) + break; + } + if (te != NULL) { rte_errno = EEXIST; - return NULL; + goto err; } te = rte_zmalloc("HASH_TAILQ_ENTRY", sizeof(*te), 0); @@ -359,13 +365,13 @@ rte_hash_create(const struct rte_hash_parameters *params) for (i = 1; i < params->entries + 1; i++) rte_ring_sp_enqueue(r, (void *)((uintptr_t) i)); - rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); te->data = (void *) h; TAILQ_INSERT_TAIL(hash_list, te, next); rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); return h; err: + rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); rte_free(te); rte_free(h); rte_free(buckets); -- 2.1.4