lkml.org 
[lkml]   [2022]   [Jun]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V7 5/5] riscv: Add qspinlock support
    Date
    From: Guo Ren <guoren@linux.alibaba.com>

    Enable qspinlock by 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 provides cheap atomic_fetch_or_acquire() with RCsc.

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

    Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
    Signed-off-by: Guo Ren <guoren@kernel.org>
    Cc: Peter Zijlstra (Intel) <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 | 2 ++
    arch/riscv/include/asm/cmpxchg.h | 17 +++++++++++++++++
    arch/riscv/kernel/setup.c | 4 ++++
    4 files changed, 32 insertions(+)

    diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
    index 32ffef9f6e5b..47e12ab9c822 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
    + 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..2cce98c7b653 100644
    --- a/arch/riscv/include/asm/Kbuild
    +++ b/arch/riscv/include/asm/Kbuild
    @@ -2,7 +2,9 @@
    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 += qspinlock.h
    generic-y += spinlock.h
    generic-y += spinlock_types.h
    generic-y += qrwlock.h
    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" \
    diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
    index f0f36a4a0e9b..b9b234157a66 100644
    --- a/arch/riscv/kernel/setup.c
    +++ b/arch/riscv/kernel/setup.c
    @@ -295,6 +295,10 @@ void __init setup_arch(char **cmdline_p)
    setup_smp();
    #endif

    +#if !defined(CONFIG_NUMA) && defined(CONFIG_QUEUED_SPINLOCKS)
    + static_branch_disable(&use_qspinlock_key);
    +#endif
    +
    riscv_fill_hwcap();
    apply_boot_alternatives();
    }
    --
    2.36.1
    \
     
     \ /
      Last update: 2022-06-28 10:21    [W:2.771 / U:0.868 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site