Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp3367758pxb; Wed, 14 Apr 2021 04:01:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxcfhRzwWd8FV0EdV6+2W3yAK1OhvF0TYXEaUgvc8tCnohGoP/32kcDarNBzR+zQ8csw0oS X-Received: by 2002:a17:902:8f89:b029:ea:ea23:a02c with SMTP id z9-20020a1709028f89b02900eaea23a02cmr17792042plo.71.1618398119512; Wed, 14 Apr 2021 04:01:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618398119; cv=none; d=google.com; s=arc-20160816; b=WbLXPHUNat8XWQVb8n+LxkY2WY5u/QwnB83z7sqg5hMr5EZX72SH8nB9EF2YO8gXkh iCD0yxt0R/+n16tzK4/F/xOG/fja/1tgKBeyVtXI93PVMFfRlQlnpOqi5pno2mykQWCF W4ESGJWWzYTKVCo+RZpUSqISM92zbMKbxFmvBi0gyevuJ0BvXWhqqXaNWiJyGr4ltd5K ZRWCTqltoNNp8mKp/VGnz3QtASBBw39+IKFJt39vFhqkhLl6RpJy2iTPsxXqRcGCs1nn Ax2kvk0jteMRncoL09QL8IDdGoB/hx1bnVgmdSaeSK+FSzzZ+0W0ipA5KrjSanhfx5ap NgOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=CUbaMpgqOTeGscAmBT+v8HSRuAKZHpMwxHzLXqOJAiY=; b=ve9Y8TJ2VG86X7pZ5no9wNwnUb4UEoffG5pFdUmmI1m/2po9vEv0T3WXhze07LG+mM CCwiATefVnopinWNENOfAlLf5dkgz+WA2CaZ4atzgqnPgB1Hsv9iKo+mcFbDi91nVNg1 nDQkej2nY2aQsQBkG+IVK/Yfwhen+L/nvCuKDwQpD+QP9+2+V3ZNU7eFS4bD8wwLBCSj jT4vSyQJIVMgsBnSnqfQ8RjJnZirvnxIAABu2YZp8e1iBf70y39IGgt7xpB49tqlcE2z G1REjARFf/fhmPmWRay9yPPVt26ZJ9EBXTiu+LNH0jEdSh3jxZ1iiWDCoIZ5YICIAWFK mY1Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=APFSIBF7; 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 o4si19800699pfk.309.2021.04.14.04.01.24; Wed, 14 Apr 2021 04:01:59 -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=APFSIBF7; 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 S233044AbhDNAYZ (ORCPT + 99 others); Tue, 13 Apr 2021 20:24:25 -0400 Received: from mail.kernel.org ([198.145.29.99]:56678 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229914AbhDNAYZ (ORCPT ); Tue, 13 Apr 2021 20:24:25 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2A833613B6 for ; Wed, 14 Apr 2021 00:24:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1618359845; bh=xovKbGed2hWLO46ZuqrlITDm4dbGTaznZbIgqZ9WyXg=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=APFSIBF7YveeiBYs2S0tL7Kh5qTOGxIRIdVCDSczSi4HEc41sLIm2c947gDziZGah TwFcbRmvki3xpDLJc125eZEr6aUv9hxXafSBQSgfsrDmuJ3C+WD8195HBLh3hmJJYI sjXtoFm+OI6GWEfCVzh7w62AlW8Y7rrpAgvpKXhbUN3WIvBsm39W0oJ4Dv9xd8czDT tSaMtB5pNO3TfDTxwij0gD/49rfzWrSpFfO7YQpMDLe7js9YZWPAfCaTNdvcQyqn4Y E9CmQWO8Ow9/lk3xRX2T6NGwQ+n64bKbcDdQWCPSQsQ+0ZYre1hmST2ry+Wt/vVK0C UpcMlWI2b858w== Received: by mail-lf1-f51.google.com with SMTP id e14so17440266lfn.11 for ; Tue, 13 Apr 2021 17:24:05 -0700 (PDT) X-Gm-Message-State: AOAM531kKhDkdBK3dhLmN4OHgMkp8OzQ12gQETHaK7K8afp/yhwGnqmw ByCEr7I1fmSHaxOx45FTayXiiRCouibOj3AqkWI= X-Received: by 2002:a05:6512:3ca7:: with SMTP id h39mr25005082lfv.346.1618359843478; Tue, 13 Apr 2021 17:24:03 -0700 (PDT) MIME-Version: 1.0 References: <20210413093059.GB15806@arm.com> In-Reply-To: <20210413093059.GB15806@arm.com> From: Guo Ren Date: Wed, 14 Apr 2021 08:23:51 +0800 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH] riscv: locks: introduce ticket-based spinlock implementation To: Catalin Marinas Cc: =?UTF-8?Q?Christoph_M=C3=BCllner?= , Peter Zijlstra , Palmer Dabbelt , Anup Patel , linux-riscv , Linux Kernel Mailing List , Guo Ren , Will Deacon , Arnd Bergmann Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Apr 13, 2021 at 5:31 PM Catalin Marinas w= rote: > > On Tue, Apr 13, 2021 at 11:22:40AM +0200, Christoph M=C3=BCllner wrote: > > On Tue, Apr 13, 2021 at 10:03 AM Peter Zijlstra = wrote: > > > On Mon, Apr 12, 2021 at 11:54:55PM +0200, Christoph M=C3=BCllner wrot= e: > > > > On Mon, Apr 12, 2021 at 7:33 PM Palmer Dabbelt = wrote: > > > > > My plan is to add a generic ticket-based lock, which can be selec= ted at > > > > > compile time. It'll have no architecture dependencies (though it= 'll > > > > > likely have some hooks for architectures that can make this go fa= ster). > > > > > Users can then just pick which spinlock flavor they want, with th= e idea > > > > > being that smaller systems will perform better with ticket locks = and > > > > > larger systems will perform better with queued locks. The main g= oal > > > > > here is to give the less widely used architectures an easy way to= have > > > > > fair locks, as right now we've got a lot of code duplication beca= use any > > > > > architecture that wants ticket locks has to do it themselves. > > > > > > > > In the case of LL/SC sequences, we have a maximum of 16 instruction= s > > > > on RISC-V. My concern with a pure-C implementation would be that > > > > we cannot guarantee this (e.g. somebody wants to compile with -O0) > > > > and I don't know of a way to abort the build in case this limit exc= eeds. > > > > Therefore I have preferred inline assembly for OpenSBI (my initial = idea > > > > was to use closure-like LL/SC macros, where you can write the loop > > > > in form of C code). > > > > > > For ticket locks you really only needs atomic_fetch_add() and > > > smp_store_release() and an architectural guarantees that the > > > atomic_fetch_add() has fwd progress under contention and that a sub-w= ord > > > store (through smp_store_release()) will fail the SC. > > > > > > Then you can do something like: > > > > > > void lock(atomic_t *lock) > > > { > > > u32 val =3D atomic_fetch_add(1<<16, lock); /* SC, gives us RC= sc */ > > > u16 ticket =3D val >> 16; > > > > > > for (;;) { > > > if (ticket =3D=3D (u16)val) > > > break; > > > cpu_relax(); > > > val =3D atomic_read_acquire(lock); > > > } > > > } > > > > > > void unlock(atomic_t *lock) > > > { > > > u16 *ptr =3D (u16 *)lock + (!!__BIG_ENDIAN__); > > > u32 val =3D atomic_read(lock); > > > > > > smp_store_release(ptr, (u16)val + 1); > > > } > > > > > > That's _almost_ as simple as a test-and-set :-) It isn't quite optima= l > > > on x86 for not being allowed to use a memop on unlock, since its bein= g > > > forced into a load-store because of all the volatile, but whatever. > > > > What about trylock()? > > I.e. one could implement trylock() without a loop, by letting > > trylock() fail if the SC fails. > > That looks safe on first view, but nobody does this right now. I think it's safe for riscv LR/SC, because in spec A 8.3 section: "As a consequence of the eventuality guarantee, if some harts in an execution environment are executing constrained LR/SC loops, and no other harts or devices in the execution environment execute an unconditional store or AMO to that reservation set, then at least one hart will eventually exit its constrained LR/SC loop." So it guarantees LR/SC pair: CPU0 CPU1 =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D LR addr1 LR addr1 SC addr1 // guarantee success. SC addr1 But not guarantee, another hart unconditional store (which I mentioned befo= re): u32 a =3D 0x55aa66bb; u16 *ptr =3D &a; CPU0 CPU1 =3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D xchg16(ptr, new) while(1) WRITE_ONCE(*(ptr + 1), x); > > Not familiar with RISC-V but I'd recommend that a trylock only fails if > the lock is locked (after LR). A SC may fail for other reasons > (cacheline eviction; depending on the microarchitecture) even if the > lock is unlocked. At least on arm64 we had this issue with an > implementation having a tendency to always fail the first STXR. I think it's a broken implementation for riscv. SC couldn't fail by cache line bouncing and only could fail by another real write. That means the HW implementation should use a per-hart address monitor not just grab the cache line into the exclusive state without lockdown the SNOOP channel. I think the implementation of LR/SC you mentioned is a gambling style but broke the riscv spec. Is the patch of Will's would fix up the problem you mentioned? ---- commit 9bb17be062de6f5a9c9643258951aa0935652ec3 Author: Will Deacon Date: Tue Jul 2 14:54:33 2013 +0100 ARM: locks: prefetch the destination word for write prior to strex The cost of changing a cacheline from shared to exclusive state can be significant, especially when this is triggered by an exclusive store, since it may result in having to retry the transaction. This patch prefixes our {spin,read,write}_[try]lock implementations wit= h pldw instructions (on CPUs which support them) to try and grab the line in exclusive state from the start. arch_rwlock_t is changed to avoid using a volatile member, since this generates compiler warnings when falling back on the __builtin_prefetch intrinsic which expects a const void * argument. Acked-by: Nicolas Pitre Signed-off-by: Will Deacon ---- In the end, I want to conclude my suggestions here: - Using ticket-lock as default - Using ARCH_USE_QUEUED_SPINLOCKS_XCHG32 for riscv qspinlock - Disable xhg16/cmxchg16 and any sub-word atomic primitive in riscv -- Best Regards Guo Ren ML: https://lore.kernel.org/linux-csky/