From patchwork Wed Aug 26 09:20:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Diogo Behrens X-Patchwork-Id: 75983 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 28E66A04B1; Wed, 26 Aug 2020 11:20:38 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 73EF44F9C; Wed, 26 Aug 2020 11:20:37 +0200 (CEST) Received: from huawei.com (lhrrgout.huawei.com [185.176.76.210]) by dpdk.org (Postfix) with ESMTP id CC6E41F1C for ; Wed, 26 Aug 2020 11:20:35 +0200 (CEST) Received: from lhreml728-chm.china.huawei.com (unknown [172.18.7.106]) by Forcepoint Email with ESMTP id 1E0625CE3FFC13825177; Wed, 26 Aug 2020 10:20:34 +0100 (IST) Received: from debian.fritz.box (10.198.195.7) by lhreml728-chm.china.huawei.com (10.201.108.79) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1913.5; Wed, 26 Aug 2020 10:20:16 +0100 From: Diogo Behrens To: Phil Yang CC: Date: Wed, 26 Aug 2020 11:20:02 +0200 Message-ID: <20200826092002.19395-1-diogo.behrens@huawei.com> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 X-Originating-IP: [10.198.195.7] X-ClientProxiedBy: lhreml727-chm.china.huawei.com (10.201.108.78) To lhreml728-chm.china.huawei.com (10.201.108.79) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH] librte_eal: fix mcslock hang on weak memory 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" The initialization me->locked=1 in lock() must happen before next->locked=0 in unlock(), otherwise a thread may hang forever, waiting me->locked become 0. On weak memory systems (such as ARMv8), the current implementation allows me->locked=1 to be reordered with announcing the node (pred->next=me) and, consequently, to be reordered with next->locked=0 in unlock(). This fix adds a release barrier to pred->next=me, forcing me->locked=1 to happen before this operation. Signed-off-by: Diogo Behrens Acked-by: Honnappa Nagarahalli --- lib/librte_eal/include/generic/rte_mcslock.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/include/generic/rte_mcslock.h b/lib/librte_eal/include/generic/rte_mcslock.h index 2bef28351..ce553f547 100644 --- a/lib/librte_eal/include/generic/rte_mcslock.h +++ b/lib/librte_eal/include/generic/rte_mcslock.h @@ -68,7 +68,14 @@ rte_mcslock_lock(rte_mcslock_t **msl, rte_mcslock_t *me) */ return; } - __atomic_store_n(&prev->next, me, __ATOMIC_RELAXED); + /* The store to me->next above should also complete before the node is + * visible to predecessor thread releasing the lock. Hence, the store + * prev->next also requires release semantics. Note that, for example, + * on ARM, the release semantics in the exchange operation is not + * strong as a release fence and is not sufficient to enforce the + * desired order here. + */ + __atomic_store_n(&prev->next, me, __ATOMIC_RELEASE); /* The while-load of me->locked should not move above the previous * store to prev->next. Otherwise it will cause a deadlock. Need a