Received: by 10.223.185.116 with SMTP id b49csp4893256wrg; Wed, 7 Mar 2018 02:56:06 -0800 (PST) X-Google-Smtp-Source: AG47ELtHIdBdnDLpvTimQrIz3cRcdCx/231IDJYD9TEU3vB5324My/Wcem3DfZtqUUcqm5sgPdME X-Received: by 10.98.17.86 with SMTP id z83mr22229067pfi.207.1520420165971; Wed, 07 Mar 2018 02:56:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520420165; cv=none; d=google.com; s=arc-20160816; b=XmA3IVL2DBvOhrxaH5xtcsGjmzjQQAwMRSiG71Bk4sixG+kEaNrNMcIs3pk19qJ/8Y AtiEbsVKB/O5UP+1JTPtnjebm7HNTxYlgzvLzPCWtDkIlA2zAuLAU3lOjFQg+yuwpQzY wWEuAwbEUBka39lpGLio1hYAomKaqzl9s+nbr4qHR/Ua2K54N4LFtQ0u7+IgCa8Tedjf t1YbEp+hoJ59LvOLKB/OH2vgR5mqNoM/ZTROizQcx30b0OxZdkssMikixl5WF799Npx+ Yi9860RARrb9rMTie4ioOFULEL0UAeVQkhQFuSXeJvRekW3fXKIVq9p3LKvY/E8JVVfU p0uA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=6bQYLit2tIH5/bLG10QQj2H3RuPid9XGypi5uIUE0z4=; b=eanrkTO/w5R8A9dlshrRVsYPI1++JuptGeT2lbEMA7xRsVTn1uuGBAisxKOf7tw16t QlHC9l4kMo4Mhy1KAbwUqz5y5ceXUyLRrj5CQ2FQQcJLj/E5798WBW3SpNY2ibfOHYuY psD3weniTg5Bsrg8qGcV5PA1UCpHW1Jmjv6o7l+gxnVCxAlAY7+9GHqchn/HeL0MN2kY czdDQFSAL07pevR7/Vp5IWOJWcBEw55s88b3wvU5sIHQIOSSQ9rlVL3dNPLwKW18/u5P mBrmDBKU5cM1rnnGfj/GFKG+5Cz+Lt+aqT+geR+HdD3ASVVP+VmKr7hj0Sd0CnDB3hmQ ca6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=FLS17k50; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g1si11074231pgc.726.2018.03.07.02.55.51; Wed, 07 Mar 2018 02:56:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=FLS17k50; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932801AbeCGKw5 (ORCPT + 99 others); Wed, 7 Mar 2018 05:52:57 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:53759 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751234AbeCGKwx (ORCPT ); Wed, 7 Mar 2018 05:52:53 -0500 Received: by mail-wm0-f65.google.com with SMTP id e194so3872149wmd.3 for ; Wed, 07 Mar 2018 02:52:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=6bQYLit2tIH5/bLG10QQj2H3RuPid9XGypi5uIUE0z4=; b=FLS17k50MIMeElgigxJnPhq8kA3sdJe23ToGozTiHFwjiCbqp79rNzzd+4WsEO8srF WT4nKsAcf4S18BUERTSy1eoUMvuz6smrn/IIrkeyaD8HAGCNpEC9I0fBdfZwURQomO1D gcG8x+jj0X3Z4/k0QvYAs+39Vwq1TT+Zjx/HZ9EWStJi2n7r1QHwhcGHBCgY/nLTN945 EGY9rcjgyG7GqnDllOywutlieeCOZwWctg5vvveWtsJPDWh/sqk/KChwVmSDZVqrCv65 0MNaC5PPw5710aTnZsUEV6lbRG6e2F4PYulF3MrPipHY3d2xkAqled7fD0tOoziMhJob WHbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=6bQYLit2tIH5/bLG10QQj2H3RuPid9XGypi5uIUE0z4=; b=FjUttk9Arvec27xPrlQY1nfvpn7hgFCdw+CKk0+TWDY71rdKnNsMHaCITbCKUFT9cR +B93Co5o7hOjwdiXmGQw7O3QNSg72M6xKjuCa++0K35VgJHqlSgLyJ0PD/Ha7BcLRkV8 0nk7kW4JNv3j4CNjbClSEXq0vJdunyJpUNP7WsjpBntgdnJdOlT6sgyMAPNMTrIUIAlm KKmYNeTpmx7E0ur3lUZ8em5uIJgmcsGPujngUgydP4YwYwXVO9xNsOeN4deZVP5/7TFG NULhjeI9y0xUSz/iP4NB8O4rmqObu/qg9AqgFoOUKTqMuy1Dc+15rKF1eoSEbJgglsq8 mSaA== X-Gm-Message-State: AElRT7Gerg1BdOq5bMhkxLRaFvWZp0YWYjOoYTFVLXzWSnf+3Ezxf3nT xvrG+SwwNBXb5o4DBOPU86Y= X-Received: by 10.28.237.21 with SMTP id l21mr6966434wmh.12.1520419971966; Wed, 07 Mar 2018 02:52:51 -0800 (PST) Received: from andrea (85.100.broadband17.iol.cz. [109.80.100.85]) by smtp.gmail.com with ESMTPSA id a72sm11343372wme.28.2018.03.07.02.52.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Mar 2018 02:52:51 -0800 (PST) Date: Wed, 7 Mar 2018 11:52:42 +0100 From: Andrea Parri To: Palmer Dabbelt Cc: albert@sifive.com, Daniel Lustig , stern@rowland.harvard.edu, Will Deacon , peterz@infradead.org, boqun.feng@gmail.com, npiggin@gmail.com, dhowells@redhat.com, j.alglave@ucl.ac.uk, luc.maranget@inria.fr, paulmck@linux.vnet.ibm.com, akiyks@gmail.com, mingo@kernel.org, Linus Torvalds , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH 1/2] riscv/spinlock: Strengthen implementations with fences Message-ID: <20180307105242.GA6133@andrea> References: <1520274249-21815-1-git-send-email-parri.andrea@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 06, 2018 at 06:02:28PM -0800, Palmer Dabbelt wrote: > On Mon, 05 Mar 2018 10:24:09 PST (-0800), parri.andrea@gmail.com wrote: > >Current implementations map locking operations using .rl and .aq > >annotations. However, this mapping is unsound w.r.t. the kernel > >memory consistency model (LKMM) [1]: > > > >Referring to the "unlock-lock-read-ordering" test reported below, > >Daniel wrote: > > > > "I think an RCpc interpretation of .aq and .rl would in fact > > allow the two normal loads in P1 to be reordered [...] > > > > The intuition would be that the amoswap.w.aq can forward from > > the amoswap.w.rl while that's still in the store buffer, and > > then the lw x3,0(x4) can also perform while the amoswap.w.rl > > is still in the store buffer, all before the l1 x1,0(x2) > > executes. That's not forbidden unless the amoswaps are RCsc, > > unless I'm missing something. > > > > Likewise even if the unlock()/lock() is between two stores. > > A control dependency might originate from the load part of > > the amoswap.w.aq, but there still would have to be something > > to ensure that this load part in fact performs after the store > > part of the amoswap.w.rl performs globally, and that's not > > automatic under RCpc." > > > >Simulation of the RISC-V memory consistency model confirmed this > >expectation. > > > >In order to "synchronize" LKMM and RISC-V's implementation, this > >commit strengthens the implementations of the locking operations > >by replacing .rl and .aq with the use of ("lightweigth") fences, > >resp., "fence rw, w" and "fence r , rw". > > > >C unlock-lock-read-ordering > > > >{} > >/* s initially owned by P1 */ > > > >P0(int *x, int *y) > >{ > > WRITE_ONCE(*x, 1); > > smp_wmb(); > > WRITE_ONCE(*y, 1); > >} > > > >P1(int *x, int *y, spinlock_t *s) > >{ > > int r0; > > int r1; > > > > r0 = READ_ONCE(*y); > > spin_unlock(s); > > spin_lock(s); > > r1 = READ_ONCE(*x); > >} > > > >exists (1:r0=1 /\ 1:r1=0) > > > >[1] https://marc.info/?l=linux-kernel&m=151930201102853&w=2 > > https://groups.google.com/a/groups.riscv.org/forum/#!topic/isa-dev/hKywNHBkAXM > > https://marc.info/?l=linux-kernel&m=151633436614259&w=2 > > > >Signed-off-by: Andrea Parri > >Cc: Palmer Dabbelt > >Cc: Albert Ou > >Cc: Daniel Lustig > >Cc: Alan Stern > >Cc: Will Deacon > >Cc: Peter Zijlstra > >Cc: Boqun Feng > >Cc: Nicholas Piggin > >Cc: David Howells > >Cc: Jade Alglave > >Cc: Luc Maranget > >Cc: "Paul E. McKenney" > >Cc: Akira Yokosawa > >Cc: Ingo Molnar > >Cc: Linus Torvalds > >Cc: linux-riscv@lists.infradead.org > >Cc: linux-kernel@vger.kernel.org > >--- > > arch/riscv/include/asm/fence.h | 12 ++++++++++++ > > arch/riscv/include/asm/spinlock.h | 29 +++++++++++++++-------------- > > 2 files changed, 27 insertions(+), 14 deletions(-) > > create mode 100644 arch/riscv/include/asm/fence.h > > Oh, sorry about this -- I thought I'd deleted all this code, but I guess I > just wrote a patch and then forgot about it. Here's my original patch, > which I have marked as a WIP: No problem. > > commit 39908f1f8b75ae88ce44dc77b8219a94078ad298 > Author: Palmer Dabbelt > Date: Tue Dec 5 16:26:50 2017 -0800 > > RISC-V: Use generic spin and rw locks > > This might not be exactly the right thing to do: we could use LR/SC to > produce slightly better locks by rolling the tests into the LR/SC. I'm > going to defer that until I get a better handle on the new memory model > and just be safe here: after some discussion I'm pretty sure the AMOs > are good, and cmpxchg is safe (by being way too string). I'm pretty sure you lost me (and a few other people) here. IIUC, this says: "what we've been discussing within the last few weeks is going to change", but not much else... Or am I misunderstanding? You mean cmpxchg, ... as in my patch 2/2? > > Since we'd want to rewrite the spinlocks anyway so they queue, I don't > see any reason to keep the old implementations around. Keep in mind that queued locks were written and optimized for x86. arm64 only recently adopted qrwlocks: 087133ac90763cd339b6b67f2998f87dcc136c52 ("locking/qrwlock, arm64: Move rwlock implementation over to qrwlocks") This certainly needs further testing and reviewing. (Nit: your patch does not compile on any of the "riscv" branches I'm currently tracking...) Andrea > > Signed-off-by: Palmer Dabbelt > > diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h > index 2fd27e8ef1fd..9b166ea81fe5 100644 > --- a/arch/riscv/include/asm/spinlock.h > +++ b/arch/riscv/include/asm/spinlock.h > @@ -15,128 +15,7 @@ > #ifndef _ASM_RISCV_SPINLOCK_H > #define _ASM_RISCV_SPINLOCK_H > > -#include > -#include > - > -/* > - * Simple spin lock operations. These provide no fairness guarantees. > - */ > - > -/* FIXME: Replace this with a ticket lock, like MIPS. */ > - > -#define arch_spin_is_locked(x) (READ_ONCE((x)->lock) != 0) > - > -static inline void arch_spin_unlock(arch_spinlock_t *lock) > -{ > - __asm__ __volatile__ ( > - "amoswap.w.rl x0, x0, %0" > - : "=A" (lock->lock) > - :: "memory"); > -} > - > -static inline int arch_spin_trylock(arch_spinlock_t *lock) > -{ > - int tmp = 1, busy; > - > - __asm__ __volatile__ ( > - "amoswap.w.aq %0, %2, %1" > - : "=r" (busy), "+A" (lock->lock) > - : "r" (tmp) > - : "memory"); > - > - return !busy; > -} > - > -static inline void arch_spin_lock(arch_spinlock_t *lock) > -{ > - while (1) { > - if (arch_spin_is_locked(lock)) > - continue; > - > - if (arch_spin_trylock(lock)) > - break; > - } > -} > - > -/***********************************************************/ > - > -static inline void arch_read_lock(arch_rwlock_t *lock) > -{ > - int tmp; > - > - __asm__ __volatile__( > - "1: lr.w %1, %0\n" > - " bltz %1, 1b\n" > - " addi %1, %1, 1\n" > - " sc.w.aq %1, %1, %0\n" > - " bnez %1, 1b\n" > - : "+A" (lock->lock), "=&r" (tmp) > - :: "memory"); > -} > - > -static inline void arch_write_lock(arch_rwlock_t *lock) > -{ > - int tmp; > - > - __asm__ __volatile__( > - "1: lr.w %1, %0\n" > - " bnez %1, 1b\n" > - " li %1, -1\n" > - " sc.w.aq %1, %1, %0\n" > - " bnez %1, 1b\n" > - : "+A" (lock->lock), "=&r" (tmp) > - :: "memory"); > -} > - > -static inline int arch_read_trylock(arch_rwlock_t *lock) > -{ > - int busy; > - > - __asm__ __volatile__( > - "1: lr.w %1, %0\n" > - " bltz %1, 1f\n" > - " addi %1, %1, 1\n" > - " sc.w.aq %1, %1, %0\n" > - " bnez %1, 1b\n" > - "1:\n" > - : "+A" (lock->lock), "=&r" (busy) > - :: "memory"); > - > - return !busy; > -} > - > -static inline int arch_write_trylock(arch_rwlock_t *lock) > -{ > - int busy; > - > - __asm__ __volatile__( > - "1: lr.w %1, %0\n" > - " bnez %1, 1f\n" > - " li %1, -1\n" > - " sc.w.aq %1, %1, %0\n" > - " bnez %1, 1b\n" > - "1:\n" > - : "+A" (lock->lock), "=&r" (busy) > - :: "memory"); > - > - return !busy; > -} > - > -static inline void arch_read_unlock(arch_rwlock_t *lock) > -{ > - __asm__ __volatile__( > - "amoadd.w.rl x0, %1, %0" > - : "+A" (lock->lock) > - : "r" (-1) > - : "memory"); > -} > - > -static inline void arch_write_unlock(arch_rwlock_t *lock) > -{ > - __asm__ __volatile__ ( > - "amoswap.w.rl x0, x0, %0" > - : "=A" (lock->lock) > - :: "memory"); > -} > +#include > +#include > > #endif /* _ASM_RISCV_SPINLOCK_H */ >