From patchwork Thu Oct 4 16:35:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Yipeng1" X-Patchwork-Id: 46105 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 F11711B105; Fri, 5 Oct 2018 01:41:12 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 8B5585F2C for ; Fri, 5 Oct 2018 01:41:10 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Oct 2018 16:41:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,342,1534834800"; d="scan'208";a="268585020" Received: from skx-yipeng.jf.intel.com ([10.54.81.175]) by fmsmga005.fm.intel.com with ESMTP; 04 Oct 2018 16:41:08 -0700 From: Yipeng Wang To: bruce.richardson@intel.com Cc: konstantin.ananyev@intel.com, dev@dpdk.org, yipeng1.wang@intel.com, honnappa.nagarahalli@arm.com, sameh.gobriel@intel.com, dharmik.thakkar@arm.com Date: Thu, 4 Oct 2018 09:35:44 -0700 Message-Id: <1538670947-277429-2-git-send-email-yipeng1.wang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1538670947-277429-1-git-send-email-yipeng1.wang@intel.com> References: <1537993618-92630-1-git-send-email-yipeng1.wang@intel.com> <1538670947-277429-1-git-send-email-yipeng1.wang@intel.com> Subject: [dpdk-dev] [PATCH v6 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 --- 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 */