Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp875134pxb; Thu, 15 Apr 2021 08:32:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzIrOCrt1X1zOkjkX5vFu/v0NQA4ps2u8ryOqkw4u7n/sY25MWl23ZdMNCHV5Avq/nLKmAh X-Received: by 2002:a17:906:4a89:: with SMTP id x9mr3988877eju.121.1618500747310; Thu, 15 Apr 2021 08:32:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618500747; cv=none; d=google.com; s=arc-20160816; b=YEquRRXNu5PpUsQjUzRcQMe+qVsnpQLIi+KpNg7lRRDXEPDFuw39tzR5zB9eHFfVvb TW8NaiebypRgjwyXN6s5nIVsaE6amJkGT7QeqUL/NZQzNo7eTDR4kR0SHeUt4NoaloJ9 CuTfVa1h0Y4MSGePoPW235AVq2JQmEjJDSuwQi67AL16MKKeKJjox20ImX7bBlyWqKh4 5Fo1WPYKN+rOIWKSKEwMBNgtWUJ7x+e0TvSipw7NV+9AdB4omnq26Jg9iQKxKEljNM+k 2GhpWKXoGbdYc93G8qSWGHKiVgitiDQv12oGMgNWUOE5NY4TsA5/COMxTDEEs6GldHvC yDbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=gZV/tRyZiJ0aXGLxT4dABGKO7uLUwLIqOILcn1wAIdQ=; b=JiZLoqU4RsAAu+yPvCFd0WBvABzo4hjnF4BvKTF5nYcowpcq8CUpxiJSKcSidEeus8 6987bl6LBWegsBlhxliUX8vF5IbYOnKzL/kICrigcAp4rz9C/oT4OpBE97bGV6d3nqsI qhbpl45j//wF/s6c7zl7SBap2kd4nZvpYJ4FYUXk7v8az3Hf8SN7Rq3J6NAnu7+p8i2Q VZfcIzy9n5z/bSkHexYkXQ223fkSzEsi8MnOMUyusJReCLo2vTS19B1zMxEjLvMrzEFV g4cGCBJwqXmBW3xnfszy3EOFCzv+3WWAkks35K2U88GzZdDxRkspN4w9ca3bBwiR5WQe z4uQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=dhqx9dJt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j26si2647969edq.124.2021.04.15.08.32.04; Thu, 15 Apr 2021 08:32:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=dhqx9dJt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233363AbhDOP2y (ORCPT + 99 others); Thu, 15 Apr 2021 11:28:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:59834 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231137AbhDOP2t (ORCPT ); Thu, 15 Apr 2021 11:28:49 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A21376115B; Thu, 15 Apr 2021 15:28:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1618500506; bh=rcKwsyBG71spLEI7owmKnHtzbC9TKpBz3yV7qSke48I=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=dhqx9dJtE0XYy7xv/0AUzW2pyMnZVCO3iYLenf7XXHMqIhVNBBBAua+GG/A4Xb+Dp GFU1QTekLmOtvcP1sbRsm4YCfDdf4ckcKoXM0awzeLL3ynfKUYDW+U1ER551NXj4cp D01HpsZjuuARWkcEpiBd3Zum2KhDYLrkklYhNhb7VYcbxkZ6ETN7W6RTqiFv3tO3D0 05Ps6ze5kcjpHmJ6jPX83cRGNHqlfULHlUcM2opA5ttIHYZVVW39vamvxNNHc+BmL/ 6ykDd6zJdesew8WZ6BvcU40VGnlshECgb4tuYo1+BPaXxKw6IOd6HJ+nz0NFdo1fua OTdV/vnEIZ1bA== Date: Thu, 15 Apr 2021 16:28:21 +0100 From: Will Deacon To: Peter Zijlstra Cc: Ali Saidi , linux-kernel@vger.kernel.org, catalin.marinas@arm.com, steve.capper@arm.com, benh@kernel.crashing.org, stable@vger.kernel.org, Ingo Molnar , Waiman Long , Boqun Feng Subject: Re: [PATCH] locking/qrwlock: Fix ordering in queued_write_lock_slowpath Message-ID: <20210415152820.GB26439@willie-the-truck> References: <20210415142552.30916-1-alisaidi@amazon.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Apr 15, 2021 at 05:03:58PM +0200, Peter Zijlstra wrote: > On Thu, Apr 15, 2021 at 02:25:52PM +0000, Ali Saidi wrote: > > While this code is executed with the wait_lock held, a reader can > > acquire the lock without holding wait_lock. The writer side loops > > checking the value with the atomic_cond_read_acquire(), but only truly > > acquires the lock when the compare-and-exchange is completed > > successfully which isn’t ordered. The other atomic operations from this > > point are release-ordered and thus reads after the lock acquisition can > > be completed before the lock is truly acquired which violates the > > guarantees the lock should be making. > > Should be per who? We explicitly do not order the lock acquire store. > qspinlock has the exact same issue. > > If you look in the git history surrounding spin_is_locked(), you'll find > 'lovely' things. > > Basically, if you're doing crazy things with spin_is_locked() you get to > keep the pieces. > > > Fixes: b519b56e378ee ("locking/qrwlock: Use atomic_cond_read_acquire() when spinning in qrwloc") > > Signed-off-by: Ali Saidi > > Cc: stable@vger.kernel.org > > --- > > kernel/locking/qrwlock.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/kernel/locking/qrwlock.c b/kernel/locking/qrwlock.c > > index 4786dd271b45..10770f6ac4d9 100644 > > --- a/kernel/locking/qrwlock.c > > +++ b/kernel/locking/qrwlock.c > > @@ -73,8 +73,8 @@ void queued_write_lock_slowpath(struct qrwlock *lock) > > > > /* When no more readers or writers, set the locked flag */ > > do { > > - atomic_cond_read_acquire(&lock->cnts, VAL == _QW_WAITING); > > - } while (atomic_cmpxchg_relaxed(&lock->cnts, _QW_WAITING, > > + atomic_cond_read_relaxed(&lock->cnts, VAL == _QW_WAITING); > > + } while (atomic_cmpxchg_acquire(&lock->cnts, _QW_WAITING, > > _QW_LOCKED) != _QW_WAITING); > > unlock: > > arch_spin_unlock(&lock->wait_lock); > > This doesn't make sense, there is no such thing as a store-acquire. What > you're doing here is moving the acquire from one load to the next. A > load we know will load the exact same value. > > Also see Documentation/atomic_t.txt: > > {}_acquire: the R of the RMW (or atomic_read) is an ACQUIRE > > > If anything this code wants to be written like so. > > --- > > diff --git a/kernel/locking/qrwlock.c b/kernel/locking/qrwlock.c > index 4786dd271b45..22aeccc363ca 100644 > --- a/kernel/locking/qrwlock.c > +++ b/kernel/locking/qrwlock.c > @@ -60,6 +60,8 @@ EXPORT_SYMBOL(queued_read_lock_slowpath); > */ > void queued_write_lock_slowpath(struct qrwlock *lock) > { > + u32 cnt; > + > /* Put the writer into the wait queue */ > arch_spin_lock(&lock->wait_lock); > > @@ -73,9 +75,8 @@ void queued_write_lock_slowpath(struct qrwlock *lock) > > /* When no more readers or writers, set the locked flag */ > do { > - atomic_cond_read_acquire(&lock->cnts, VAL == _QW_WAITING); > - } while (atomic_cmpxchg_relaxed(&lock->cnts, _QW_WAITING, > - _QW_LOCKED) != _QW_WAITING); > + cnt = atomic_cond_read_acquire(&lock->cnts, VAL == _QW_WAITING); I think the issue is that >here< a concurrent reader in interrupt context can take the lock and release it again, but we could speculate reads from the critical section up over the later release and up before the control dependency here... > + } while (!atomic_try_cmpxchg_relaxed(&lock->cnts, &cnt, _QW_LOCKED)); ... and then this cmpxchg() will succeed, so our speculated stale reads could be used. *HOWEVER* Speculating a read should be fine in the face of a concurrent _reader_, so for this to be an issue it implies that the reader is also doing some (atomic?) updates. Ali? Will