From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 0FACA293B for ; Tue, 5 Apr 2016 13:05:49 +0200 (CEST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP; 05 Apr 2016 04:05:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,443,1455004800"; d="scan'208";a="79324033" Received: from irsmsx102.ger.corp.intel.com ([163.33.3.155]) by fmsmga004.fm.intel.com with ESMTP; 05 Apr 2016 04:05:48 -0700 Received: from irsmsx108.ger.corp.intel.com ([169.254.11.13]) by IRSMSX102.ger.corp.intel.com ([169.254.2.19]) with mapi id 14.03.0248.002; Tue, 5 Apr 2016 12:05:47 +0100 From: "De Lara Guarch, Pablo" To: Olivier Matz , "dev@dpdk.org" CC: "Richardson, Bruce" Thread-Topic: [dpdk-dev] [PATCH v2 3/4] hash: keep the list locked at creation Thread-Index: AQHRjw4EiWWslS0f+0WuUbS0f0qLvJ97NoLw Date: Tue, 5 Apr 2016 11:05:46 +0000 Message-ID: References: <1459351827-3346-1-git-send-email-olivier.matz@6wind.com> <1459841759-23296-1-git-send-email-olivier.matz@6wind.com> <1459841759-23296-4-git-send-email-olivier.matz@6wind.com> In-Reply-To: <1459841759-23296-4-git-send-email-olivier.matz@6wind.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiYTc3NzJiNjItOTFhMC00NzI3LTlhNzMtOGZjNmJiMzRiYjBmIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE1LjkuNi42IiwiVHJ1c3RlZExhYmVsSGFzaCI6Imt1a1BGaVk3d3hmXC9qUHlJUTkreWhcL0Z4WHB4OEY5YjE2OFVERHNyUnlGUT0ifQ== x-ctpclassification: CTP_IC x-originating-ip: [163.33.239.181] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v2 3/4] hash: keep the list locked at creation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Apr 2016 11:05:50 -0000 > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz > Sent: Tuesday, April 05, 2016 8:36 AM > To: dev@dpdk.org > Cc: Richardson, Bruce > Subject: [dpdk-dev] [PATCH v2 3/4] hash: keep the list locked at creation >=20 > 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. >=20 > As the lock is held by the rte_ring_create(), move its creation at the > beginning of the function and only take the lock after the ring is > created to avoid a deadlock. >=20 > Signed-off-by: Olivier Matz > --- > lib/librte_hash/rte_cuckoo_hash.c | 68 ++++++++++++++++++++++-----------= -- > ---- > 1 file changed, 38 insertions(+), 30 deletions(-) >=20 > diff --git a/lib/librte_hash/rte_cuckoo_hash.c > b/lib/librte_hash/rte_cuckoo_hash.c > index ccec2db..63a74fd 100644 > --- a/lib/librte_hash/rte_cuckoo_hash.c > +++ b/lib/librte_hash/rte_cuckoo_hash.c > @@ -226,19 +226,46 @@ rte_hash_create(const struct rte_hash_parameters > *params) > if (params->extra_flag & > RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT) > hw_trans_mem_support =3D 1; >=20 > + /* Store all keys and leave the first entry as a dummy entry for > lookup_bulk */ > + if (hw_trans_mem_support) > + /* > + * Increase number of slots by total number of indices > + * that can be stored in the lcore caches > + * except for the first cache > + */ > + num_key_slots =3D params->entries + (RTE_MAX_LCORE - 1) * > + LCORE_CACHE_SIZE + 1; > + else > + num_key_slots =3D params->entries + 1; > + > + snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name); > + r =3D rte_ring_create(ring_name, rte_align32pow2(num_key_slots), > + params->socket_id, 0); > + if (r =3D=3D NULL) { > + RTE_LOG(ERR, HASH, "memory allocation failed\n"); > + goto err; > + } > + > snprintf(hash_name, sizeof(hash_name), "HT_%s", params->name); >=20 > - /* Guarantee there's no existing */ > - h =3D rte_hash_find_existing(params->name); > - if (h !=3D NULL) { > + rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); > + > + /* guarantee there's no existing: this is normally already checked > + * by ring creation above */ > + TAILQ_FOREACH(te, hash_list, next) { > + h =3D (struct rte_hash *) te->data; > + if (strncmp(params->name, h->name, RTE_HASH_NAMESIZE) > =3D=3D 0) > + break; > + } > + if (te !=3D NULL) { > rte_errno =3D EEXIST; > - return NULL; > + goto err_unlock; > } >=20 > te =3D rte_zmalloc("HASH_TAILQ_ENTRY", sizeof(*te), 0); > if (te =3D=3D NULL) { > RTE_LOG(ERR, HASH, "tailq entry allocation failed\n"); > - goto err; > + goto err_unlock; > } >=20 > h =3D (struct rte_hash *)rte_zmalloc_socket(hash_name, sizeof(struct > rte_hash), > @@ -246,7 +273,7 @@ rte_hash_create(const struct rte_hash_parameters > *params) >=20 > if (h =3D=3D NULL) { > RTE_LOG(ERR, HASH, "memory allocation failed\n"); > - goto err; > + goto err_unlock; > } >=20 > const uint32_t num_buckets =3D rte_align32pow2(params->entries) > @@ -258,23 +285,10 @@ rte_hash_create(const struct rte_hash_parameters > *params) >=20 > if (buckets =3D=3D NULL) { > RTE_LOG(ERR, HASH, "memory allocation failed\n"); > - goto err; > + goto err_unlock; > } >=20 > const uint32_t key_entry_size =3D sizeof(struct rte_hash_key) + > params->key_len; > - > - /* Store all keys and leave the first entry as a dummy entry for > lookup_bulk */ > - if (hw_trans_mem_support) > - /* > - * Increase number of slots by total number of indices > - * that can be stored in the lcore caches > - * except for the first cache > - */ > - num_key_slots =3D params->entries + (RTE_MAX_LCORE - 1) * > - LCORE_CACHE_SIZE + 1; > - else > - num_key_slots =3D params->entries + 1; > - > const uint64_t key_tbl_size =3D (uint64_t) key_entry_size * > num_key_slots; >=20 > k =3D rte_zmalloc_socket(NULL, key_tbl_size, > @@ -282,7 +296,7 @@ rte_hash_create(const struct rte_hash_parameters > *params) >=20 > if (k =3D=3D NULL) { > RTE_LOG(ERR, HASH, "memory allocation failed\n"); > - goto err; > + goto err_unlock; > } >=20 > /* > @@ -325,14 +339,6 @@ rte_hash_create(const struct rte_hash_parameters > *params) > h->rte_hash_cmp_eq =3D memcmp; > #endif >=20 > - snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name); > - r =3D rte_ring_create(ring_name, rte_align32pow2(num_key_slots), > - params->socket_id, 0); > - if (r =3D=3D NULL) { > - RTE_LOG(ERR, HASH, "memory allocation failed\n"); > - goto err; > - } > - > if (hw_trans_mem_support) { > h->local_free_slots =3D rte_zmalloc_socket(NULL, > sizeof(struct lcore_cache) * RTE_MAX_LCORE, > @@ -359,13 +365,15 @@ rte_hash_create(const struct rte_hash_parameters > *params) > for (i =3D 1; i < params->entries + 1; i++) > rte_ring_sp_enqueue(r, (void *)((uintptr_t) i)); >=20 > - rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); > te->data =3D (void *) h; > TAILQ_INSERT_TAIL(hash_list, te, next); > rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); > > return h; > +err_unlock: > + rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); > err: > + rte_ring_free(r); This patch does not apply cleanly, since another patch for this file last w= eek was applied (http://dpdk.org/dev/patchwork/patch/11896/). Could you rebase this patchset against mainline? Thanks, Pablo