diff mbox series

[V5] riscv: Add qspinlock support

Message ID 20220620155404.1968739-1-guoren@kernel.org (mailing list archive)
State New, archived
Headers show
Series [V5] riscv: Add qspinlock support | expand

Commit Message

Guo Ren June 20, 2022, 3:54 p.m. UTC
From: Guo Ren <guoren@linux.alibaba.com>

Enable qspinlock and meet the requirements mentioned in a8ad07e5240c9
("asm-generic: qspinlock: Indicate the use of mixed-size atomics").

 - RISC-V atomic_*_release()/atomic_*_acquire() are implemented with
   own relaxed version plus acquire/release_fence for RCsc
   synchronization.

 - RISC-V LR/SC pairs could provide a strong/weak forward guarantee
   that depends on micro-architecture. And RISC-V ISA spec has given
   out several limitations to let hardware support strict forward
   guarantee (RISC-V User ISA - 8.3 Eventual Success of
   Store-Conditional Instructions). Some riscv cores such as BOOMv3
   & XiangShan could provide strict & strong forward guarantee (The
   cache line would be kept in an exclusive state for Backoff cycles,
   and only this core's interrupt could break the LR/SC pair).

 - RISC-V could provide cheap atomic_fetch_or_acquire() with RCsc.

 - RISC-V only provides relaxed xhg16 to support qspinlock.

The first version of patch was made in 2019.1 [1]. The second version
was made in 2020.11 [2].

[1] https://lore.kernel.org/linux-riscv/20190211043829.30096-1-michaeljclark@mac.com/#r
[2] https://lore.kernel.org/linux-riscv/1606225437-22948-2-git-send-email-guoren@kernel.org/

Change V5:
 - Update comment with RISC-V forward guarantee feature.
 - Back to V3 direction and optimize asm code.

Change V4:
 - Remove custom sub-word xchg implementation
 - Add ARCH_USE_QUEUED_SPINLOCKS_XCHG32 in locking/qspinlock

Change V3:
 - Coding convention by Peter Zijlstra's advices

Change V2:
 - Coding convention in cmpxchg.h
 - Re-implement short xchg
 - Remove char & cmpxchg implementations

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Palmer Dabbelt <palmer@rivosinc.com>
---
 arch/riscv/Kconfig                      |  9 +++++++++
 arch/riscv/include/asm/Kbuild           |  4 ++--
 arch/riscv/include/asm/cmpxchg.h        | 16 ++++++++++++++++
 arch/riscv/include/asm/spinlock.h       | 12 ++++++++++++
 arch/riscv/include/asm/spinlock_types.h | 12 ++++++++++++
 5 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 arch/riscv/include/asm/spinlock.h
 create mode 100644 arch/riscv/include/asm/spinlock_types.h

Comments

Conor Dooley June 20, 2022, 3:57 p.m. UTC | #1
On 20/06/2022 16:54, guoren@kernel.org wrote:
> From: Guo Ren <guoren@linux.alibaba.com>
> 
> Enable qspinlock and meet the requirements mentioned in a8ad07e5240c9
> ("asm-generic: qspinlock: Indicate the use of mixed-size atomics").
> 
>  - RISC-V atomic_*_release()/atomic_*_acquire() are implemented with
>    own relaxed version plus acquire/release_fence for RCsc
>    synchronization.
> 
>  - RISC-V LR/SC pairs could provide a strong/weak forward guarantee
>    that depends on micro-architecture. And RISC-V ISA spec has given
>    out several limitations to let hardware support strict forward
>    guarantee (RISC-V User ISA - 8.3 Eventual Success of
>    Store-Conditional Instructions). Some riscv cores such as BOOMv3
>    & XiangShan could provide strict & strong forward guarantee (The
>    cache line would be kept in an exclusive state for Backoff cycles,
>    and only this core's interrupt could break the LR/SC pair).
> 
>  - RISC-V could provide cheap atomic_fetch_or_acquire() with RCsc.
> 
>  - RISC-V only provides relaxed xhg16 to support qspinlock.
> 
> The first version of patch was made in 2019.1 [1]. The second version
> was made in 2020.11 [2].
> 
> [1] https://lore.kernel.org/linux-riscv/20190211043829.30096-1-michaeljclark@mac.com/#r
> [2] https://lore.kernel.org/linux-riscv/1606225437-22948-2-git-send-email-guoren@kernel.org/
> 
> Change V5:
>  - Update comment with RISC-V forward guarantee feature.
>  - Back to V3 direction and optimize asm code.
> 
> Change V4:
>  - Remove custom sub-word xchg implementation
>  - Add ARCH_USE_QUEUED_SPINLOCKS_XCHG32 in locking/qspinlock
> 
> Change V3:
>  - Coding convention by Peter Zijlstra's advices
> 
> Change V2:
>  - Coding convention in cmpxchg.h
>  - Re-implement short xchg
>  - Remove char & cmpxchg implementations

Hey,
How come the changelog is inside the commit message?
I assume its a copy paste error..
Thanks,
Conor.

> 
> Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Waiman Long <longman@redhat.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Palmer Dabbelt <palmer@rivosinc.com>
> ---
>  arch/riscv/Kconfig                      |  9 +++++++++
>  arch/riscv/include/asm/Kbuild           |  4 ++--
>  arch/riscv/include/asm/cmpxchg.h        | 16 ++++++++++++++++
>  arch/riscv/include/asm/spinlock.h       | 12 ++++++++++++
>  arch/riscv/include/asm/spinlock_types.h | 12 ++++++++++++
>  5 files changed, 51 insertions(+), 2 deletions(-)
>  create mode 100644 arch/riscv/include/asm/spinlock.h
>  create mode 100644 arch/riscv/include/asm/spinlock_types.h
> 
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 32ffef9f6e5b..3b0b117b4e95 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -333,6 +333,15 @@ config NODES_SHIFT
>  	  Specify the maximum number of NUMA Nodes available on the target
>  	  system.  Increases memory reserved to accommodate various tables.
>  
> +config RISCV_USE_QUEUED_SPINLOCKS
> +	bool "Using queued spinlock instead of ticket-lock"
> +	depends on SMP && MMU
> +	select ARCH_USE_QUEUED_SPINLOCKS
> +	default y if NUMA
> +	help
> +	  Make sure your micro arch LL/SC has a strong forward progress guarantee.
> +	  Otherwise, stay at ticket-lock.
> +
>  config RISCV_ALTERNATIVE
>  	bool
>  	depends on !XIP_KERNEL
> diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
> index 504f8b7e72d4..e066ccab6417 100644
> --- a/arch/riscv/include/asm/Kbuild
> +++ b/arch/riscv/include/asm/Kbuild
> @@ -2,10 +2,10 @@
>  generic-y += early_ioremap.h
>  generic-y += flat.h
>  generic-y += kvm_para.h
> +generic-y += mcs_spinlock.h
>  generic-y += parport.h
> -generic-y += spinlock.h
> -generic-y += spinlock_types.h
>  generic-y += qrwlock.h
>  generic-y += qrwlock_types.h
> +generic-y += qspinlock.h
>  generic-y += user.h
>  generic-y += vmlinux.lds.h
> diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
> index 12debce235e5..f7f8e359d3ac 100644
> --- a/arch/riscv/include/asm/cmpxchg.h
> +++ b/arch/riscv/include/asm/cmpxchg.h
> @@ -17,6 +17,22 @@
>  	__typeof__(new) __new = (new);					\
>  	__typeof__(*(ptr)) __ret;					\
>  	switch (size) {							\
> +	case 2:								\
> +		u32 temp;						\
> +		u32 shif = ((ulong)__ptr & 2) ? 16 : 0;			\
> +		u32 mask = 0xffff << shif;				\
> +		__ptr = (__typeof__(ptr))((ulong)__ptr & ~(ulong)2);	\
> +		__asm__ __volatile__ (					\
> +			"0:	lr.w %0, %2\n"				\
> +			"	and  %1, %0, %z3\n"			\
> +			"	or   %1, %1, %z4\n"			\
> +			"	sc.w %1, %1, %2\n"			\
> +			"	bnez %1, 0b\n"				\
> +			: "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)	\
> +			: "rJ" (~mask), "rJ" (__new << shif)		\
> +			: "memory");					\
> +		__ret = (__ret & mask) >> shif;				\
> +		break;							\
>  	case 4:								\
>  		__asm__ __volatile__ (					\
>  			"	amoswap.w %0, %2, %1\n"			\
> diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
> new file mode 100644
> index 000000000000..fd3fd09cff52
> --- /dev/null
> +++ b/arch/riscv/include/asm/spinlock.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_SPINLOCK_H
> +#define __ASM_SPINLOCK_H
> +
> +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
> +#include <asm/qspinlock.h>
> +#include <asm/qrwlock.h>
> +#else
> +#include <asm-generic/spinlock.h>
> +#endif
> +
> +#endif /* __ASM_SPINLOCK_H */
> diff --git a/arch/riscv/include/asm/spinlock_types.h b/arch/riscv/include/asm/spinlock_types.h
> new file mode 100644
> index 000000000000..9281237b5f4e
> --- /dev/null
> +++ b/arch/riscv/include/asm/spinlock_types.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_SPINLOCK_TYPES_H
> +#define __ASM_SPINLOCK_TYPES_H
> +
> +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
> +#include <asm-generic/qspinlock_types.h>
> +#include <asm-generic/qrwlock_types.h>
> +#else
> +#include <asm-generic/spinlock_types.h>
> +#endif
> +
> +#endif /* __ASM_SPINLOCK_TYPES_H */
kernel test robot June 20, 2022, 7:57 p.m. UTC | #2
Hi,

I love your patch! Yet something to improve:

[auto build test ERROR on soc/for-next]
[also build test ERROR on linus/master v5.19-rc2 next-20220617]
[cannot apply to tip/locking/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/guoren-kernel-org/riscv-Add-qspinlock-support/20220620-235653
base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
config: riscv-rv32_defconfig (https://download.01.org/0day-ci/archive/20220621/202206210303.Vjl4rpPv-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project af6d2a0b6825e71965f3e2701a63c239fa0ad70f)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/326f4a13941845b6ef1c4f4eaba049fe265f52bf
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review guoren-kernel-org/riscv-Add-qspinlock-support/20220620-235653
        git checkout 326f4a13941845b6ef1c4f4eaba049fe265f52bf
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv prepare

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:7:
   In file included from include/linux/gfp.h:6:
   In file included from include/linux/mmzone.h:8:
   In file included from include/linux/spinlock.h:62:
   In file included from include/linux/lockdep.h:14:
   In file included from include/linux/smp.h:13:
   In file included from include/linux/cpumask.h:13:
   In file included from include/linux/atomic.h:7:
>> arch/riscv/include/asm/atomic.h:299:1: error: expected expression
   ATOMIC_OPS()
   ^
   arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
           ATOMIC_OP(int,   , 4)
           ^
   arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
           return __xchg_relaxed(&(v->counter), n, size);                  \
                  ^
   arch/riscv/include/asm/cmpxchg.h:21:3: note: expanded from macro '__xchg_relaxed'
                   u32 temp;                                               \
                   ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:7:
   In file included from include/linux/gfp.h:6:
   In file included from include/linux/mmzone.h:8:
   In file included from include/linux/spinlock.h:62:
   In file included from include/linux/lockdep.h:14:
   In file included from include/linux/smp.h:13:
   In file included from include/linux/cpumask.h:13:
   In file included from include/linux/atomic.h:7:
>> arch/riscv/include/asm/atomic.h:299:1: error: use of undeclared identifier 'temp'; did you mean 'bcmp'?
   arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
           ATOMIC_OP(int,   , 4)
           ^
   arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
           return __xchg_relaxed(&(v->counter), n, size);                  \
                  ^
   arch/riscv/include/asm/cmpxchg.h:31:28: note: expanded from macro '__xchg_relaxed'
                           : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
                                                   ^
   include/linux/string.h:159:12: note: 'bcmp' declared here
   extern int bcmp(const void *,const void *,__kernel_size_t);
              ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:7:
   In file included from include/linux/gfp.h:6:
   In file included from include/linux/mmzone.h:8:
   In file included from include/linux/spinlock.h:62:
   In file included from include/linux/lockdep.h:14:
   In file included from include/linux/smp.h:13:
   In file included from include/linux/cpumask.h:13:
   In file included from include/linux/atomic.h:7:
>> arch/riscv/include/asm/atomic.h:299:1: error: invalid lvalue in asm output
   ATOMIC_OPS()
   ^~~~~~~~~~~~
   arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
           ATOMIC_OP(int,   , 4)
           ^~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
           return __xchg_relaxed(&(v->counter), n, size);                  \
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   arch/riscv/include/asm/cmpxchg.h:31:28: note: expanded from macro '__xchg_relaxed'
                           : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
                                                   ^~~~
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:7:
   In file included from include/linux/gfp.h:6:
   In file included from include/linux/mmzone.h:8:
   In file included from include/linux/spinlock.h:62:
   In file included from include/linux/lockdep.h:14:
   In file included from include/linux/smp.h:13:
   In file included from include/linux/cpumask.h:13:
   In file included from include/linux/atomic.h:7:
>> arch/riscv/include/asm/atomic.h:299:1: warning: mixing declarations and code is incompatible with standards before C99 [-Wdeclaration-after-statement]
   arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
           ATOMIC_OP(int,   , 4)
           ^
   arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
           return __xchg_relaxed(&(v->counter), n, size);                  \
                  ^
   arch/riscv/include/asm/cmpxchg.h:22:7: note: expanded from macro '__xchg_relaxed'
                   u32 shif = ((ulong)__ptr & 2) ? 16 : 0;                 \
                       ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:700:
   In file included from include/linux/huge_mm.h:8:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:97:11: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
                   return (set->sig[3] | set->sig[2] |
                           ^        ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
           unsigned long sig[_NSIG_WORDS];
           ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:700:
   In file included from include/linux/huge_mm.h:8:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:97:25: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
                   return (set->sig[3] | set->sig[2] |
                                         ^        ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
           unsigned long sig[_NSIG_WORDS];
           ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:700:
   In file included from include/linux/huge_mm.h:8:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:113:11: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
                   return  (set1->sig[3] == set2->sig[3]) &&
                            ^         ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
           unsigned long sig[_NSIG_WORDS];
           ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:700:
   In file included from include/linux/huge_mm.h:8:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:113:27: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
                   return  (set1->sig[3] == set2->sig[3]) &&
                                            ^         ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
           unsigned long sig[_NSIG_WORDS];
           ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:700:
   In file included from include/linux/huge_mm.h:8:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:114:5: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
                           (set1->sig[2] == set2->sig[2]) &&
                            ^         ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
           unsigned long sig[_NSIG_WORDS];
           ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:700:
   In file included from include/linux/huge_mm.h:8:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:114:21: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
                           (set1->sig[2] == set2->sig[2]) &&
                                            ^         ~
   include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
           unsigned long sig[_NSIG_WORDS];
           ^
   In file included from arch/riscv/kernel/asm-offsets.c:10:
   In file included from include/linux/mm.h:700:
   In file included from include/linux/huge_mm.h:8:
   In file included from include/linux/fs.h:33:
   In file included from include/linux/percpu-rwsem.h:7:
   In file included from include/linux/rcuwait.h:6:
   In file included from include/linux/sched/signal.h:6:
   include/linux/signal.h:156:1: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
   _SIG_SET_BINOP(sigorsets, _sig_or)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/signal.h:137:8: note: expanded from macro '_SIG_SET_BINOP'
                   a3 = a->sig[3]; a2 = a->sig[2];                         \
                        ^      ~


vim +299 arch/riscv/include/asm/atomic.h

fab957c11efe2f Palmer Dabbelt 2017-07-10  298  
5ce6c1f3535fa8 Andrea Parri   2018-03-09 @299  ATOMIC_OPS()
fab957c11efe2f Palmer Dabbelt 2017-07-10  300
Arnd Bergmann June 20, 2022, 8:42 p.m. UTC | #3
On Mon, Jun 20, 2022 at 5:54 PM <guoren@kernel.org> wrote:
> >+config RISCV_USE_QUEUED_SPINLOCKS
> +       bool "Using queued spinlock instead of ticket-lock"

Maybe we can just make ARCH_USE_QUEUED_SPINLOCKS
user visible and give users the choice between the two generic
implementations across all architectures that support the qspinlock
variant.

In arch/riscv, you'd then just have a

        select ARCH_HAVE_QUEUED_SPINLOCKS

diff --git a/arch/riscv/include/asm/spinlock.h
b/arch/riscv/include/asm/spinlock.h
> new file mode 100644
> index 000000000000..fd3fd09cff52
> --- /dev/null
> +++ b/arch/riscv/include/asm/spinlock.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ASM_SPINLOCK_H
> +#define __ASM_SPINLOCK_H
> +
> +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
> +#include <asm/qspinlock.h>
> +#include <asm/qrwlock.h>
> +#else
> +#include <asm-generic/spinlock.h>
> +#endif
> +

Along the same lines:

I think I'd prefer the header changes to be done in the asm-generic
version of this file, so this can be shared across all architectures
that want to give the choice between ticket and queued spinlock.

        Arnd
Waiman Long June 20, 2022, 9:16 p.m. UTC | #4
On 6/20/22 16:42, Arnd Bergmann wrote:
> On Mon, Jun 20, 2022 at 5:54 PM <guoren@kernel.org> wrote:
>>> +config RISCV_USE_QUEUED_SPINLOCKS
>> +       bool "Using queued spinlock instead of ticket-lock"
> Maybe we can just make ARCH_USE_QUEUED_SPINLOCKS
> user visible and give users the choice between the two generic
> implementations across all architectures that support the qspinlock
> variant.
>
> In arch/riscv, you'd then just have a
>
>          select ARCH_HAVE_QUEUED_SPINLOCKS
>
> diff --git a/arch/riscv/include/asm/spinlock.h
> b/arch/riscv/include/asm/spinlock.h
>> new file mode 100644
>> index 000000000000..fd3fd09cff52
>> --- /dev/null
>> +++ b/arch/riscv/include/asm/spinlock.h
>> @@ -0,0 +1,12 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +#ifndef __ASM_SPINLOCK_H
>> +#define __ASM_SPINLOCK_H
>> +
>> +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
>> +#include <asm/qspinlock.h>
>> +#include <asm/qrwlock.h>
>> +#else
>> +#include <asm-generic/spinlock.h>
>> +#endif
>> +
> Along the same lines:
>
> I think I'd prefer the header changes to be done in the asm-generic
> version of this file, so this can be shared across all architectures
> that want to give the choice between ticket and queued spinlock.

I concur. Qspinlock is only needed if we want to support systems with a 
large number of CPUs. For systems with a small number of CPUs. It 
doesn't matter if qspinlock or the ticket lock is being used.

Cheers,
Longman
Guo Ren June 20, 2022, 10:47 p.m. UTC | #5
On Tue, Jun 21, 2022 at 5:16 AM Waiman Long <longman@redhat.com> wrote:
>
>
> On 6/20/22 16:42, Arnd Bergmann wrote:
> > On Mon, Jun 20, 2022 at 5:54 PM <guoren@kernel.org> wrote:
> >>> +config RISCV_USE_QUEUED_SPINLOCKS
> >> +       bool "Using queued spinlock instead of ticket-lock"
> > Maybe we can just make ARCH_USE_QUEUED_SPINLOCKS
> > user visible and give users the choice between the two generic
> > implementations across all architectures that support the qspinlock
> > variant.
> >
> > In arch/riscv, you'd then just have a
> >
> >          select ARCH_HAVE_QUEUED_SPINLOCKS
> >
> > diff --git a/arch/riscv/include/asm/spinlock.h
> > b/arch/riscv/include/asm/spinlock.h
> >> new file mode 100644
> >> index 000000000000..fd3fd09cff52
> >> --- /dev/null
> >> +++ b/arch/riscv/include/asm/spinlock.h
> >> @@ -0,0 +1,12 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 */
> >> +#ifndef __ASM_SPINLOCK_H
> >> +#define __ASM_SPINLOCK_H
> >> +
> >> +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
> >> +#include <asm/qspinlock.h>
> >> +#include <asm/qrwlock.h>
> >> +#else
> >> +#include <asm-generic/spinlock.h>
> >> +#endif
> >> +
> > Along the same lines:
> >
> > I think I'd prefer the header changes to be done in the asm-generic
> > version of this file, so this can be shared across all architectures
> > that want to give the choice between ticket and queued spinlock.
>
> I concur. Qspinlock is only needed if we want to support systems with a
> large number of CPUs. For systems with a small number of CPUs. It
> doesn't matter if qspinlock or the ticket lock is being used.
RISC-V has had NUMA scenario. Think two AI chips with CCIX ports, they
could be flexibly connected when needed.

>
> Cheers,
> Longman
>
Guo Ren June 20, 2022, 10:53 p.m. UTC | #6
Is it a clang problem? GCC is okay. I would appreciate any help on the problem.

On Tue, Jun 21, 2022 at 3:58 AM kernel test robot <lkp@intel.com> wrote:
>
> Hi,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on soc/for-next]
> [also build test ERROR on linus/master v5.19-rc2 next-20220617]
> [cannot apply to tip/locking/core]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/guoren-kernel-org/riscv-Add-qspinlock-support/20220620-235653
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
> config: riscv-rv32_defconfig (https://download.01.org/0day-ci/archive/20220621/202206210303.Vjl4rpPv-lkp@intel.com/config)
> compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project af6d2a0b6825e71965f3e2701a63c239fa0ad70f)
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # install riscv cross compiling tool for clang build
>         # apt-get install binutils-riscv-linux-gnu
>         # https://github.com/intel-lab-lkp/linux/commit/326f4a13941845b6ef1c4f4eaba049fe265f52bf
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review guoren-kernel-org/riscv-Add-qspinlock-support/20220620-235653
>         git checkout 326f4a13941845b6ef1c4f4eaba049fe265f52bf
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv prepare
>
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
>
> All error/warnings (new ones prefixed by >>):
>
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: error: expected expression
>    ATOMIC_OPS()
>    ^
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^
>    arch/riscv/include/asm/cmpxchg.h:21:3: note: expanded from macro '__xchg_relaxed'
>                    u32 temp;                                               \
>                    ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: error: use of undeclared identifier 'temp'; did you mean 'bcmp'?
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^
>    arch/riscv/include/asm/cmpxchg.h:31:28: note: expanded from macro '__xchg_relaxed'
>                            : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
>                                                    ^
>    include/linux/string.h:159:12: note: 'bcmp' declared here
>    extern int bcmp(const void *,const void *,__kernel_size_t);
>               ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: error: invalid lvalue in asm output
>    ATOMIC_OPS()
>    ^~~~~~~~~~~~
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^~~~~~~~~~~~~~~~~~~~~
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    arch/riscv/include/asm/cmpxchg.h:31:28: note: expanded from macro '__xchg_relaxed'
>                            : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
>                                                    ^~~~
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: warning: mixing declarations and code is incompatible with standards before C99 [-Wdeclaration-after-statement]
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^
>    arch/riscv/include/asm/cmpxchg.h:22:7: note: expanded from macro '__xchg_relaxed'
>                    u32 shif = ((ulong)__ptr & 2) ? 16 : 0;                 \
>                        ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:97:11: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return (set->sig[3] | set->sig[2] |
>                            ^        ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:97:25: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return (set->sig[3] | set->sig[2] |
>                                          ^        ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:113:11: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return  (set1->sig[3] == set2->sig[3]) &&
>                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:113:27: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return  (set1->sig[3] == set2->sig[3]) &&
>                                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:114:5: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                            (set1->sig[2] == set2->sig[2]) &&
>                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:114:21: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                            (set1->sig[2] == set2->sig[2]) &&
>                                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:156:1: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>    _SIG_SET_BINOP(sigorsets, _sig_or)
>    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/signal.h:137:8: note: expanded from macro '_SIG_SET_BINOP'
>                    a3 = a->sig[3]; a2 = a->sig[2];                         \
>                         ^      ~
>
>
> vim +299 arch/riscv/include/asm/atomic.h
>
> fab957c11efe2f Palmer Dabbelt 2017-07-10  298
> 5ce6c1f3535fa8 Andrea Parri   2018-03-09 @299  ATOMIC_OPS()
> fab957c11efe2f Palmer Dabbelt 2017-07-10  300
>
> --
> 0-DAY CI Kernel Test Service
> https://01.org/lkp



--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/
Guo Ren June 20, 2022, 11:02 p.m. UTC | #7
On Tue, Jun 21, 2022 at 4:42 AM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Mon, Jun 20, 2022 at 5:54 PM <guoren@kernel.org> wrote:
> > >+config RISCV_USE_QUEUED_SPINLOCKS
> > +       bool "Using queued spinlock instead of ticket-lock"
>
> Maybe we can just make ARCH_USE_QUEUED_SPINLOCKS
> user visible and give users the choice between the two generic
> implementations across all architectures that support the qspinlock
> variant.
>
> In arch/riscv, you'd then just have a
>
>         select ARCH_HAVE_QUEUED_SPINLOCKS
Good point, but I think it should be another cross-arch cleanup
patchset, let's put qspinlock in riscv first with the current
framework.

>
> diff --git a/arch/riscv/include/asm/spinlock.h
> b/arch/riscv/include/asm/spinlock.h
> > new file mode 100644
> > index 000000000000..fd3fd09cff52
> > --- /dev/null
> > +++ b/arch/riscv/include/asm/spinlock.h
> > @@ -0,0 +1,12 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef __ASM_SPINLOCK_H
> > +#define __ASM_SPINLOCK_H
> > +
> > +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
> > +#include <asm/qspinlock.h>
> > +#include <asm/qrwlock.h>
> > +#else
> > +#include <asm-generic/spinlock.h>
> > +#endif
> > +
>
> Along the same lines:
>
> I think I'd prefer the header changes to be done in the asm-generic
> version of this file, so this can be shared across all architectures
> that want to give the choice between ticket and queued spinlock.
I would put the above part in the series, but they would base on the
riscv qspinlock patch.

>
>         Arnd
Guo Ren June 21, 2022, 2:19 p.m. UTC | #8
Okay

On Mon, Jun 20, 2022 at 11:58 PM <Conor.Dooley@microchip.com> wrote:
>
>
>
> On 20/06/2022 16:54, guoren@kernel.org wrote:
> > From: Guo Ren <guoren@linux.alibaba.com>
> >
> > Enable qspinlock and meet the requirements mentioned in a8ad07e5240c9
> > ("asm-generic: qspinlock: Indicate the use of mixed-size atomics").
> >
> >  - RISC-V atomic_*_release()/atomic_*_acquire() are implemented with
> >    own relaxed version plus acquire/release_fence for RCsc
> >    synchronization.
> >
> >  - RISC-V LR/SC pairs could provide a strong/weak forward guarantee
> >    that depends on micro-architecture. And RISC-V ISA spec has given
> >    out several limitations to let hardware support strict forward
> >    guarantee (RISC-V User ISA - 8.3 Eventual Success of
> >    Store-Conditional Instructions). Some riscv cores such as BOOMv3
> >    & XiangShan could provide strict & strong forward guarantee (The
> >    cache line would be kept in an exclusive state for Backoff cycles,
> >    and only this core's interrupt could break the LR/SC pair).
> >
> >  - RISC-V could provide cheap atomic_fetch_or_acquire() with RCsc.
> >
> >  - RISC-V only provides relaxed xhg16 to support qspinlock.
> >
> > The first version of patch was made in 2019.1 [1]. The second version
> > was made in 2020.11 [2].
> >
> > [1] https://lore.kernel.org/linux-riscv/20190211043829.30096-1-michaeljclark@mac.com/#r
> > [2] https://lore.kernel.org/linux-riscv/1606225437-22948-2-git-send-email-guoren@kernel.org/
> >
> > Change V5:
> >  - Update comment with RISC-V forward guarantee feature.
> >  - Back to V3 direction and optimize asm code.
> >
> > Change V4:
> >  - Remove custom sub-word xchg implementation
> >  - Add ARCH_USE_QUEUED_SPINLOCKS_XCHG32 in locking/qspinlock
> >
> > Change V3:
> >  - Coding convention by Peter Zijlstra's advices
> >
> > Change V2:
> >  - Coding convention in cmpxchg.h
> >  - Re-implement short xchg
> >  - Remove char & cmpxchg implementations
>
> Hey,
> How come the changelog is inside the commit message?
> I assume its a copy paste error..
> Thanks,
> Conor.
>
> >
> > Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren@kernel.org>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: Waiman Long <longman@redhat.com>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Palmer Dabbelt <palmer@rivosinc.com>
> > ---
> >  arch/riscv/Kconfig                      |  9 +++++++++
> >  arch/riscv/include/asm/Kbuild           |  4 ++--
> >  arch/riscv/include/asm/cmpxchg.h        | 16 ++++++++++++++++
> >  arch/riscv/include/asm/spinlock.h       | 12 ++++++++++++
> >  arch/riscv/include/asm/spinlock_types.h | 12 ++++++++++++
> >  5 files changed, 51 insertions(+), 2 deletions(-)
> >  create mode 100644 arch/riscv/include/asm/spinlock.h
> >  create mode 100644 arch/riscv/include/asm/spinlock_types.h
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 32ffef9f6e5b..3b0b117b4e95 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -333,6 +333,15 @@ config NODES_SHIFT
> >         Specify the maximum number of NUMA Nodes available on the target
> >         system.  Increases memory reserved to accommodate various tables.
> >
> > +config RISCV_USE_QUEUED_SPINLOCKS
> > +     bool "Using queued spinlock instead of ticket-lock"
> > +     depends on SMP && MMU
> > +     select ARCH_USE_QUEUED_SPINLOCKS
> > +     default y if NUMA
> > +     help
> > +       Make sure your micro arch LL/SC has a strong forward progress guarantee.
> > +       Otherwise, stay at ticket-lock.
> > +
> >  config RISCV_ALTERNATIVE
> >       bool
> >       depends on !XIP_KERNEL
> > diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
> > index 504f8b7e72d4..e066ccab6417 100644
> > --- a/arch/riscv/include/asm/Kbuild
> > +++ b/arch/riscv/include/asm/Kbuild
> > @@ -2,10 +2,10 @@
> >  generic-y += early_ioremap.h
> >  generic-y += flat.h
> >  generic-y += kvm_para.h
> > +generic-y += mcs_spinlock.h
> >  generic-y += parport.h
> > -generic-y += spinlock.h
> > -generic-y += spinlock_types.h
> >  generic-y += qrwlock.h
> >  generic-y += qrwlock_types.h
> > +generic-y += qspinlock.h
> >  generic-y += user.h
> >  generic-y += vmlinux.lds.h
> > diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
> > index 12debce235e5..f7f8e359d3ac 100644
> > --- a/arch/riscv/include/asm/cmpxchg.h
> > +++ b/arch/riscv/include/asm/cmpxchg.h
> > @@ -17,6 +17,22 @@
> >       __typeof__(new) __new = (new);                                  \
> >       __typeof__(*(ptr)) __ret;                                       \
> >       switch (size) {                                                 \
> > +     case 2:                                                         \
> > +             u32 temp;                                               \
> > +             u32 shif = ((ulong)__ptr & 2) ? 16 : 0;                 \
> > +             u32 mask = 0xffff << shif;                              \
> > +             __ptr = (__typeof__(ptr))((ulong)__ptr & ~(ulong)2);    \
> > +             __asm__ __volatile__ (                                  \
> > +                     "0:     lr.w %0, %2\n"                          \
> > +                     "       and  %1, %0, %z3\n"                     \
> > +                     "       or   %1, %1, %z4\n"                     \
> > +                     "       sc.w %1, %1, %2\n"                      \
> > +                     "       bnez %1, 0b\n"                          \
> > +                     : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
> > +                     : "rJ" (~mask), "rJ" (__new << shif)            \
> > +                     : "memory");                                    \
> > +             __ret = (__ret & mask) >> shif;                         \
> > +             break;                                                  \
> >       case 4:                                                         \
> >               __asm__ __volatile__ (                                  \
> >                       "       amoswap.w %0, %2, %1\n"                 \
> > diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
> > new file mode 100644
> > index 000000000000..fd3fd09cff52
> > --- /dev/null
> > +++ b/arch/riscv/include/asm/spinlock.h
> > @@ -0,0 +1,12 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef __ASM_SPINLOCK_H
> > +#define __ASM_SPINLOCK_H
> > +
> > +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
> > +#include <asm/qspinlock.h>
> > +#include <asm/qrwlock.h>
> > +#else
> > +#include <asm-generic/spinlock.h>
> > +#endif
> > +
> > +#endif /* __ASM_SPINLOCK_H */
> > diff --git a/arch/riscv/include/asm/spinlock_types.h b/arch/riscv/include/asm/spinlock_types.h
> > new file mode 100644
> > index 000000000000..9281237b5f4e
> > --- /dev/null
> > +++ b/arch/riscv/include/asm/spinlock_types.h
> > @@ -0,0 +1,12 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef __ASM_SPINLOCK_TYPES_H
> > +#define __ASM_SPINLOCK_TYPES_H
> > +
> > +#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
> > +#include <asm-generic/qspinlock_types.h>
> > +#include <asm-generic/qrwlock_types.h>
> > +#else
> > +#include <asm-generic/spinlock_types.h>
> > +#endif
> > +
> > +#endif /* __ASM_SPINLOCK_TYPES_H */
Guo Ren June 21, 2022, 2:57 p.m. UTC | #9
Fixed: with "{}" protect to meet clang requirement.

diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 12debce235e5..492104d45a23 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -17,6 +17,23 @@
        __typeof__(new) __new = (new);                                  \
        __typeof__(*(ptr)) __ret;                                       \
        switch (size) {                                                 \
+       case 2: {                                                       \
+               u32 temp;                                               \
+               u32 shif = ((ulong)__ptr & 2) ? 16 : 0;                 \
+               u32 mask = 0xffff << shif;                              \
+               __ptr = (__typeof__(ptr))((ulong)__ptr & ~(ulong)2);    \
+               __asm__ __volatile__ (                                  \
+                       "0:     lr.w %0, %2\n"                          \
+                       "       and  %1, %0, %z3\n"                     \
+                       "       or   %1, %1, %z4\n"                     \
+                       "       sc.w %1, %1, %2\n"                      \
+                       "       bnez %1, 0b\n"                          \
+                       : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
+                       : "rJ" (~mask), "rJ" (__new << shif)            \
+                       : "memory");                                    \
+               __ret = (__ret & mask) >> shif;                         \
+               break;                                                  \
+       }                                                               \
        case 4:                                                         \
                __asm__ __volatile__ (                                  \
                        "       amoswap.w %0, %2, %1\n"                 \

On Tue, Jun 21, 2022 at 3:58 AM kernel test robot <lkp@intel.com> wrote:
>
> Hi,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on soc/for-next]
> [also build test ERROR on linus/master v5.19-rc2 next-20220617]
> [cannot apply to tip/locking/core]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/guoren-kernel-org/riscv-Add-qspinlock-support/20220620-235653
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
> config: riscv-rv32_defconfig (https://download.01.org/0day-ci/archive/20220621/202206210303.Vjl4rpPv-lkp@intel.com/config)
> compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project af6d2a0b6825e71965f3e2701a63c239fa0ad70f)
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # install riscv cross compiling tool for clang build
>         # apt-get install binutils-riscv-linux-gnu
>         # https://github.com/intel-lab-lkp/linux/commit/326f4a13941845b6ef1c4f4eaba049fe265f52bf
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review guoren-kernel-org/riscv-Add-qspinlock-support/20220620-235653
>         git checkout 326f4a13941845b6ef1c4f4eaba049fe265f52bf
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv prepare
>
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
>
> All error/warnings (new ones prefixed by >>):
>
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: error: expected expression
>    ATOMIC_OPS()
>    ^
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^
>    arch/riscv/include/asm/cmpxchg.h:21:3: note: expanded from macro '__xchg_relaxed'
>                    u32 temp;                                               \
>                    ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: error: use of undeclared identifier 'temp'; did you mean 'bcmp'?
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^
>    arch/riscv/include/asm/cmpxchg.h:31:28: note: expanded from macro '__xchg_relaxed'
>                            : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
>                                                    ^
>    include/linux/string.h:159:12: note: 'bcmp' declared here
>    extern int bcmp(const void *,const void *,__kernel_size_t);
>               ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: error: invalid lvalue in asm output
>    ATOMIC_OPS()
>    ^~~~~~~~~~~~
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^~~~~~~~~~~~~~~~~~~~~
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    arch/riscv/include/asm/cmpxchg.h:31:28: note: expanded from macro '__xchg_relaxed'
>                            : "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)    \
>                                                    ^~~~
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:7:
>    In file included from include/linux/gfp.h:6:
>    In file included from include/linux/mmzone.h:8:
>    In file included from include/linux/spinlock.h:62:
>    In file included from include/linux/lockdep.h:14:
>    In file included from include/linux/smp.h:13:
>    In file included from include/linux/cpumask.h:13:
>    In file included from include/linux/atomic.h:7:
> >> arch/riscv/include/asm/atomic.h:299:1: warning: mixing declarations and code is incompatible with standards before C99 [-Wdeclaration-after-statement]
>    arch/riscv/include/asm/atomic.h:292:2: note: expanded from macro 'ATOMIC_OPS'
>            ATOMIC_OP(int,   , 4)
>            ^
>    arch/riscv/include/asm/atomic.h:249:9: note: expanded from macro 'ATOMIC_OP'
>            return __xchg_relaxed(&(v->counter), n, size);                  \
>                   ^
>    arch/riscv/include/asm/cmpxchg.h:22:7: note: expanded from macro '__xchg_relaxed'
>                    u32 shif = ((ulong)__ptr & 2) ? 16 : 0;                 \
>                        ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:97:11: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return (set->sig[3] | set->sig[2] |
>                            ^        ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:97:25: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return (set->sig[3] | set->sig[2] |
>                                          ^        ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:113:11: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return  (set1->sig[3] == set2->sig[3]) &&
>                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:113:27: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                    return  (set1->sig[3] == set2->sig[3]) &&
>                                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:114:5: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                            (set1->sig[2] == set2->sig[2]) &&
>                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:114:21: warning: array index 2 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>                            (set1->sig[2] == set2->sig[2]) &&
>                                             ^         ~
>    include/uapi/asm-generic/signal.h:62:2: note: array 'sig' declared here
>            unsigned long sig[_NSIG_WORDS];
>            ^
>    In file included from arch/riscv/kernel/asm-offsets.c:10:
>    In file included from include/linux/mm.h:700:
>    In file included from include/linux/huge_mm.h:8:
>    In file included from include/linux/fs.h:33:
>    In file included from include/linux/percpu-rwsem.h:7:
>    In file included from include/linux/rcuwait.h:6:
>    In file included from include/linux/sched/signal.h:6:
>    include/linux/signal.h:156:1: warning: array index 3 is past the end of the array (which contains 2 elements) [-Warray-bounds]
>    _SIG_SET_BINOP(sigorsets, _sig_or)
>    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/signal.h:137:8: note: expanded from macro '_SIG_SET_BINOP'
>                    a3 = a->sig[3]; a2 = a->sig[2];                         \
>                         ^      ~
>
>
> vim +299 arch/riscv/include/asm/atomic.h
>
> fab957c11efe2f Palmer Dabbelt 2017-07-10  298
> 5ce6c1f3535fa8 Andrea Parri   2018-03-09 @299  ATOMIC_OPS()
> fab957c11efe2f Palmer Dabbelt 2017-07-10  300
>
> --
> 0-DAY CI Kernel Test Service
> https://01.org/lkp
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 32ffef9f6e5b..3b0b117b4e95 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -333,6 +333,15 @@  config NODES_SHIFT
 	  Specify the maximum number of NUMA Nodes available on the target
 	  system.  Increases memory reserved to accommodate various tables.
 
+config RISCV_USE_QUEUED_SPINLOCKS
+	bool "Using queued spinlock instead of ticket-lock"
+	depends on SMP && MMU
+	select ARCH_USE_QUEUED_SPINLOCKS
+	default y if NUMA
+	help
+	  Make sure your micro arch LL/SC has a strong forward progress guarantee.
+	  Otherwise, stay at ticket-lock.
+
 config RISCV_ALTERNATIVE
 	bool
 	depends on !XIP_KERNEL
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 504f8b7e72d4..e066ccab6417 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -2,10 +2,10 @@ 
 generic-y += early_ioremap.h
 generic-y += flat.h
 generic-y += kvm_para.h
+generic-y += mcs_spinlock.h
 generic-y += parport.h
-generic-y += spinlock.h
-generic-y += spinlock_types.h
 generic-y += qrwlock.h
 generic-y += qrwlock_types.h
+generic-y += qspinlock.h
 generic-y += user.h
 generic-y += vmlinux.lds.h
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 12debce235e5..f7f8e359d3ac 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -17,6 +17,22 @@ 
 	__typeof__(new) __new = (new);					\
 	__typeof__(*(ptr)) __ret;					\
 	switch (size) {							\
+	case 2:								\
+		u32 temp;						\
+		u32 shif = ((ulong)__ptr & 2) ? 16 : 0;			\
+		u32 mask = 0xffff << shif;				\
+		__ptr = (__typeof__(ptr))((ulong)__ptr & ~(ulong)2);	\
+		__asm__ __volatile__ (					\
+			"0:	lr.w %0, %2\n"				\
+			"	and  %1, %0, %z3\n"			\
+			"	or   %1, %1, %z4\n"			\
+			"	sc.w %1, %1, %2\n"			\
+			"	bnez %1, 0b\n"				\
+			: "=&r" (__ret), "=&r" (temp), "+A" (*__ptr)	\
+			: "rJ" (~mask), "rJ" (__new << shif)		\
+			: "memory");					\
+		__ret = (__ret & mask) >> shif;				\
+		break;							\
 	case 4:								\
 		__asm__ __volatile__ (					\
 			"	amoswap.w %0, %2, %1\n"			\
diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
new file mode 100644
index 000000000000..fd3fd09cff52
--- /dev/null
+++ b/arch/riscv/include/asm/spinlock.h
@@ -0,0 +1,12 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_SPINLOCK_H
+#define __ASM_SPINLOCK_H
+
+#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
+#include <asm/qspinlock.h>
+#include <asm/qrwlock.h>
+#else
+#include <asm-generic/spinlock.h>
+#endif
+
+#endif /* __ASM_SPINLOCK_H */
diff --git a/arch/riscv/include/asm/spinlock_types.h b/arch/riscv/include/asm/spinlock_types.h
new file mode 100644
index 000000000000..9281237b5f4e
--- /dev/null
+++ b/arch/riscv/include/asm/spinlock_types.h
@@ -0,0 +1,12 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifdef CONFIG_ARCH_USE_QUEUED_SPINLOCKS
+#include <asm-generic/qspinlock_types.h>
+#include <asm-generic/qrwlock_types.h>
+#else
+#include <asm-generic/spinlock_types.h>
+#endif
+
+#endif /* __ASM_SPINLOCK_TYPES_H */