From patchwork Mon Oct 22 18:39:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Yipeng1" X-Patchwork-Id: 47196 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 10BB01B1EA; Tue, 23 Oct 2018 03:45:05 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id EB03C4F98 for ; Tue, 23 Oct 2018 03:44:59 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Oct 2018 18:44:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,414,1534834800"; d="scan'208";a="102426687" Received: from skx-yipeng.jf.intel.com ([10.54.81.175]) by orsmga002.jf.intel.com with ESMTP; 22 Oct 2018 18:44:57 -0700 From: Yipeng Wang To: bruce.richardson@intel.com Cc: dev@dpdk.org, yipeng1.wang@intel.com, honnappa.nagarahalli@arm.com Date: Mon, 22 Oct 2018 11:39:45 -0700 Message-Id: <1540233588-202969-2-git-send-email-yipeng1.wang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1540233588-202969-1-git-send-email-yipeng1.wang@intel.com> References: <1540233588-202969-1-git-send-email-yipeng1.wang@intel.com> Subject: [dpdk-dev] [PATCH v8 1/4] hash: fix race condition in iterate X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" In rte_hash_iterate, the reader lock did not protect the while loop which checks empty entry. This created a race condition that the entry may become empty when enters the lock, then a wrong key data value would be read out. This commit reads out the position in the while condition, which makes sure that the position will not be changed to empty before entering the lock. Fixes: f2e3001b53ec ("hash: support read/write concurrency") Cc: stable@dpdk.org Signed-off-by: Yipeng Wang Reported-by: Honnappa Nagarahalli Reviewed-by: Honnappa Nagarahalli Acked-by: Dharmik Thakkar Acked-by: Bruce Richardson --- lib/librte_hash/rte_cuckoo_hash.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c index f7b86c8..da8ddf4 100644 --- a/lib/librte_hash/rte_cuckoo_hash.c +++ b/lib/librte_hash/rte_cuckoo_hash.c @@ -1318,7 +1318,7 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32 idx = *next % RTE_HASH_BUCKET_ENTRIES; /* If current position is empty, go to the next one */ - while (h->buckets[bucket_idx].key_idx[idx] == EMPTY_SLOT) { + while ((position = h->buckets[bucket_idx].key_idx[idx]) == EMPTY_SLOT) { (*next)++; /* End of table */ if (*next == total_entries) @@ -1326,9 +1326,8 @@ rte_hash_iterate(const struct rte_hash *h, const void **key, void **data, uint32 bucket_idx = *next / RTE_HASH_BUCKET_ENTRIES; idx = *next % RTE_HASH_BUCKET_ENTRIES; } + __hash_rw_reader_lock(h); - /* Get position of entry in key table */ - position = h->buckets[bucket_idx].key_idx[idx]; next_key = (struct rte_hash_key *) ((char *)h->key_store + position * h->key_entry_size); /* Return key and data */