[dpdk-dev,3/4] hash: keep the list locked at creation
Commit Message
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@6wind.com>
---
lib/librte_hash/rte_cuckoo_hash.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
@@ -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);