[PATCH v4 5/7] RISC-V: Move to generic spinlocks

Conor.Dooley at microchip.com Conor.Dooley at microchip.com
Thu May 5 06:00:06 PDT 2022


On 30/04/2022 16:36, Palmer Dabbelt wrote:
> From: Palmer Dabbelt <palmer at rivosinc.com>
> 
> Our existing spinlocks aren't fair and replacing them has been on the
> TODO list for a long time.  This moves to the recently-introduced ticket
> spinlocks, which are simple enough that they are likely to be correct
> and fast on the vast majority of extant implementations.
> 
> This introduces a horrible hack that allows us to split out the spinlock
> conversion from the rwlock conversion.  We have to do the spinlocks
> first because qrwlock needs fair spinlocks, but we don't want to pollute
> the asm-generic code to support the generic spinlocks without qrwlocks.
> Thus we pollute the RISC-V code, but just until the next commit as it's
> all going away.
> 
> Signed-off-by: Palmer Dabbelt <palmer at rivosinc.com>

I am loathe to add a TB tag since I have not done much by way of testing
any realistic use cases - but I have put it in our CI and have had a play
around with it locally & nothing obviously broke for me.

If you think that is sufficient:
Tested-by: Conor Dooley <conor.dooley at microchip.com>
Otherwise feel free to ignore the tag.

Thanks,
Conor.

> ---
>   arch/riscv/include/asm/Kbuild           |  2 ++
>   arch/riscv/include/asm/spinlock.h       | 44 +++----------------------
>   arch/riscv/include/asm/spinlock_types.h |  9 +++--
>   3 files changed, 10 insertions(+), 45 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
> index 5edf5b8587e7..c3f229ae8033 100644
> --- a/arch/riscv/include/asm/Kbuild
> +++ b/arch/riscv/include/asm/Kbuild
> @@ -3,5 +3,7 @@ generic-y += early_ioremap.h
>   generic-y += flat.h
>   generic-y += kvm_para.h
>   generic-y += parport.h
> +generic-y += qrwlock.h
> +generic-y += qrwlock_types.h
>   generic-y += user.h
>   generic-y += vmlinux.lds.h
> diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
> index f4f7fa1b7ca8..88a4d5d0d98a 100644
> --- a/arch/riscv/include/asm/spinlock.h
> +++ b/arch/riscv/include/asm/spinlock.h
> @@ -7,49 +7,13 @@
>   #ifndef _ASM_RISCV_SPINLOCK_H
>   #define _ASM_RISCV_SPINLOCK_H
>   
> +/* This is horible, but the whole file is going away in the next commit. */
> +#define __ASM_GENERIC_QRWLOCK_H
> +
>   #include <linux/kernel.h>
>   #include <asm/current.h>
>   #include <asm/fence.h>
> -
> -/*
> - * 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)
> -{
> -	smp_store_release(&lock->lock, 0);
> -}
> -
> -static inline int arch_spin_trylock(arch_spinlock_t *lock)
> -{
> -	int tmp = 1, busy;
> -
> -	__asm__ __volatile__ (
> -		"	amoswap.w %0, %2, %1\n"
> -		RISCV_ACQUIRE_BARRIER
> -		: "=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;
> -	}
> -}
> -
> -/***********************************************************/
> +#include <asm-generic/spinlock.h>
>   
>   static inline void arch_read_lock(arch_rwlock_t *lock)
>   {
> diff --git a/arch/riscv/include/asm/spinlock_types.h b/arch/riscv/include/asm/spinlock_types.h
> index 5a35a49505da..f2f9b5d7120d 100644
> --- a/arch/riscv/include/asm/spinlock_types.h
> +++ b/arch/riscv/include/asm/spinlock_types.h
> @@ -6,15 +6,14 @@
>   #ifndef _ASM_RISCV_SPINLOCK_TYPES_H
>   #define _ASM_RISCV_SPINLOCK_TYPES_H
>   
> +/* This is horible, but the whole file is going away in the next commit. */
> +#define __ASM_GENERIC_QRWLOCK_TYPES_H
> +
>   #ifndef __LINUX_SPINLOCK_TYPES_RAW_H
>   # error "please don't include this file directly"
>   #endif
>   
> -typedef struct {
> -	volatile unsigned int lock;
> -} arch_spinlock_t;
> -
> -#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
> +#include <asm-generic/spinlock_types.h>
>   
>   typedef struct {
>   	volatile unsigned int lock;


More information about the linux-riscv mailing list