[PATCH 3/4] hash: keep the list locked at creation
From: Olivier Matz <hidden>
Date: 2016-03-30 15:31:06
Subsystem:
library code, the rest · Maintainers:
Andrew Morton, Linus Torvalds
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 <redacted> --- 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