@@ -359,6 +359,22 @@ config NODES_SHIFT
Specify the maximum number of NUMA Nodes available on the target
system. Increases memory reserved to accommodate various tables.
+choice
+ prompt "RISC-V spinlock type"
+ default RISCV_TICKET_SPINLOCKS
+
+config RISCV_TICKET_SPINLOCKS
+ bool "Using ticket spinlock"
+
+config RISCV_QUEUED_SPINLOCKS
+ bool "Using queued spinlock"
+ depends on SMP && MMU
+ select ARCH_USE_QUEUED_SPINLOCKS
+ help
+ Make sure your micro arch LL/SC has a strong forward progress guarantee.
+ Otherwise, stay at ticket-lock.
+endchoice
+
config RISCV_ALTERNATIVE
bool
depends on !XIP_KERNEL
@@ -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
@@ -11,12 +11,36 @@
#include <asm/barrier.h>
#include <asm/fence.h>
+static inline ulong __xchg16_relaxed(ulong new, void *ptr)
+{
+ ulong ret, tmp;
+ ulong shif = ((ulong)ptr & 2) ? 16 : 0;
+ ulong mask = 0xffff << shif;
+ ulong *__ptr = (ulong *)((ulong)ptr & ~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" (tmp), "+A" (*__ptr)
+ : "rJ" (~mask), "rJ" (new << shif)
+ : "memory");
+
+ return (ulong)((ret & mask) >> shif);
+}
+
#define __xchg_relaxed(ptr, new, size) \
({ \
__typeof__(ptr) __ptr = (ptr); \
__typeof__(new) __new = (new); \
__typeof__(*(ptr)) __ret; \
switch (size) { \
+ case 2: { \
+ __ret = (__typeof__(*(ptr))) \
+ __xchg16_relaxed((ulong)__new, __ptr); \
+ break;} \
case 4: \
__asm__ __volatile__ ( \
" amoswap.w %0, %2, %1\n" \