From: guoren@kernel.org
To: palmer@rivosinc.com, heiko@sntech.de, hch@infradead.org,
arnd@arndb.de, peterz@infradead.org, will@kernel.org,
boqun.feng@gmail.com, longman@redhat.com, mingo@redhat.com,
philipp.tomsich@vrull.eu, cmuellner@linux.com,
linux-kernel@vger.kernel.org, David.Laight@ACULAB.COM
Cc: linux-riscv@lists.infradead.org, linux-csky@vger.kernel.org,
Guo Ren <guoren@linux.alibaba.com>, Guo Ren <guoren@kernel.org>
Subject: [PATCH V8 08/10] riscv: Add combo spinlock support
Date: Sun, 24 Jul 2022 08:25:15 -0400 [thread overview]
Message-ID: <20220724122517.1019187-9-guoren@kernel.org> (raw)
In-Reply-To: <20220724122517.1019187-1-guoren@kernel.org>
From: Guo Ren <guoren@linux.alibaba.com>
Combo spinlock could support queued and ticket in one Linux Image and
select them during boot time with command line option. Here is the
func-size(Bytes) comparison table below:
TYPE : COMBO | TICKET | QUEUED
arch_spin_lock : 106 | 60 | 50
arch_spin_unlock : 54 | 36 | 26
arch_spin_trylock : 110 | 72 | 54
arch_spin_is_locked : 48 | 34 | 20
arch_spin_is_contended : 56 | 40 | 24
rch_spin_value_unlocked : 48 | 34 | 24
One example of disassemble combo arch_spin_unlock:
0xffffffff8000409c <+14>: nop # jump label slot
0xffffffff800040a0 <+18>: fence rw,w # queued spinlock start
0xffffffff800040a4 <+22>: sb zero,0(a4) # queued spinlock end
0xffffffff800040a8 <+26>: ld s0,8(sp)
0xffffffff800040aa <+28>: addi sp,sp,16
0xffffffff800040ac <+30>: ret
0xffffffff800040ae <+32>: lw a5,0(a4) # ticket spinlock start
0xffffffff800040b0 <+34>: sext.w a5,a5
0xffffffff800040b2 <+36>: fence rw,w
0xffffffff800040b6 <+40>: addiw a5,a5,1
0xffffffff800040b8 <+42>: slli a5,a5,0x30
0xffffffff800040ba <+44>: srli a5,a5,0x30
0xffffffff800040bc <+46>: sh a5,0(a4) # ticket spinlock end
0xffffffff800040c0 <+50>: ld s0,8(sp)
0xffffffff800040c2 <+52>: addi sp,sp,16
0xffffffff800040c4 <+54>: ret
We could see queued spinlock is better than ticket-lock when there is no
contend into queued_spin_lock_slowpath. And combo could provide a
compatible Linux Image for a different kind of micro-arch design.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 9 +++-
arch/riscv/include/asm/Kbuild | 1 -
arch/riscv/include/asm/spinlock.h | 77 +++++++++++++++++++++++++++++++
arch/riscv/kernel/setup.c | 22 +++++++++
4 files changed, 107 insertions(+), 2 deletions(-)
create mode 100644 arch/riscv/include/asm/spinlock.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 721f098228a8..f1d68491a1cf 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -361,7 +361,7 @@ config NODES_SHIFT
choice
prompt "RISC-V spinlock type"
- default RISCV_TICKET_SPINLOCKS
+ default RISCV_COMBO_SPINLOCKS
config RISCV_TICKET_SPINLOCKS
bool "Using ticket spinlock"
@@ -373,6 +373,13 @@ config RISCV_QUEUED_SPINLOCKS
help
Make sure your micro arch LL/SC has a strong forward progress guarantee.
Otherwise, stay at ticket-lock/combo-lock.
+
+config RISCV_COMBO_SPINLOCKS
+ bool "Using combo spinlock"
+ depends on SMP && MMU
+ select ARCH_USE_QUEUED_SPINLOCKS
+ help
+ Select queued spinlock or ticket-lock with jump_label.
endchoice
config RISCV_ALTERNATIVE
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 2cce98c7b653..59d5ea7390ea 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -5,7 +5,6 @@ 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
generic-y += qrwlock_types.h
diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
new file mode 100644
index 000000000000..b079462d818b
--- /dev/null
+++ b/arch/riscv/include/asm/spinlock.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_RISCV_SPINLOCK_H
+#define __ASM_RISCV_SPINLOCK_H
+
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+#include <asm-generic/ticket_spinlock.h>
+
+#undef arch_spin_is_locked
+#undef arch_spin_is_contended
+#undef arch_spin_value_unlocked
+#undef arch_spin_lock
+#undef arch_spin_trylock
+#undef arch_spin_unlock
+
+#include <asm-generic/qspinlock.h>
+#include <linux/jump_label.h>
+
+#undef arch_spin_is_locked
+#undef arch_spin_is_contended
+#undef arch_spin_value_unlocked
+#undef arch_spin_lock
+#undef arch_spin_trylock
+#undef arch_spin_unlock
+
+DECLARE_STATIC_KEY_TRUE(qspinlock_key);
+
+static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ queued_spin_lock(lock);
+ else
+ ticket_spin_lock(lock);
+}
+
+static __always_inline bool arch_spin_trylock(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_trylock(lock);
+ return ticket_spin_trylock(lock);
+}
+
+static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ queued_spin_unlock(lock);
+ else
+ ticket_spin_unlock(lock);
+}
+
+static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_value_unlocked(lock);
+ else
+ return ticket_spin_value_unlocked(lock);
+}
+
+static __always_inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_is_locked(lock);
+ return ticket_spin_is_locked(lock);
+}
+
+static __always_inline int arch_spin_is_contended(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_is_contended(lock);
+ return ticket_spin_is_contended(lock);
+}
+#include <asm/qrwlock.h>
+#else
+#include <asm-generic/spinlock.h>
+#endif /* CONFIG_RISCV_COMBO_SPINLOCKS */
+
+#endif /* __ASM_RISCV_SPINLOCK_H */
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index f0f36a4a0e9b..b763039bf49b 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -261,6 +261,13 @@ static void __init parse_dtb(void)
#endif
}
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+DEFINE_STATIC_KEY_TRUE_RO(qspinlock_key);
+EXPORT_SYMBOL(qspinlock_key);
+
+static bool qspinlock_flag __initdata = false;
+#endif
+
void __init setup_arch(char **cmdline_p)
{
parse_dtb();
@@ -295,10 +302,25 @@ void __init setup_arch(char **cmdline_p)
setup_smp();
#endif
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+ if (!qspinlock_flag)
+ static_branch_disable(&qspinlock_key);
+#endif
+
riscv_fill_hwcap();
apply_boot_alternatives();
}
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+static int __init enable_qspinlock(char *p)
+{
+ qspinlock_flag = true;
+
+ return 0;
+}
+early_param("qspinlock", enable_qspinlock);
+#endif
+
static int __init topology_init(void)
{
int i, ret;
--
2.36.1
WARNING: multiple messages have this Message-ID (diff)
From: guoren@kernel.org
To: palmer@rivosinc.com, heiko@sntech.de, hch@infradead.org,
arnd@arndb.de, peterz@infradead.org, will@kernel.org,
boqun.feng@gmail.com, longman@redhat.com, mingo@redhat.com,
philipp.tomsich@vrull.eu, cmuellner@linux.com,
linux-kernel@vger.kernel.org, David.Laight@ACULAB.COM
Cc: linux-riscv@lists.infradead.org, linux-csky@vger.kernel.org,
Guo Ren <guoren@linux.alibaba.com>, Guo Ren <guoren@kernel.org>
Subject: [PATCH V8 08/10] riscv: Add combo spinlock support
Date: Sun, 24 Jul 2022 08:25:15 -0400 [thread overview]
Message-ID: <20220724122517.1019187-9-guoren@kernel.org> (raw)
In-Reply-To: <20220724122517.1019187-1-guoren@kernel.org>
From: Guo Ren <guoren@linux.alibaba.com>
Combo spinlock could support queued and ticket in one Linux Image and
select them during boot time with command line option. Here is the
func-size(Bytes) comparison table below:
TYPE : COMBO | TICKET | QUEUED
arch_spin_lock : 106 | 60 | 50
arch_spin_unlock : 54 | 36 | 26
arch_spin_trylock : 110 | 72 | 54
arch_spin_is_locked : 48 | 34 | 20
arch_spin_is_contended : 56 | 40 | 24
rch_spin_value_unlocked : 48 | 34 | 24
One example of disassemble combo arch_spin_unlock:
0xffffffff8000409c <+14>: nop # jump label slot
0xffffffff800040a0 <+18>: fence rw,w # queued spinlock start
0xffffffff800040a4 <+22>: sb zero,0(a4) # queued spinlock end
0xffffffff800040a8 <+26>: ld s0,8(sp)
0xffffffff800040aa <+28>: addi sp,sp,16
0xffffffff800040ac <+30>: ret
0xffffffff800040ae <+32>: lw a5,0(a4) # ticket spinlock start
0xffffffff800040b0 <+34>: sext.w a5,a5
0xffffffff800040b2 <+36>: fence rw,w
0xffffffff800040b6 <+40>: addiw a5,a5,1
0xffffffff800040b8 <+42>: slli a5,a5,0x30
0xffffffff800040ba <+44>: srli a5,a5,0x30
0xffffffff800040bc <+46>: sh a5,0(a4) # ticket spinlock end
0xffffffff800040c0 <+50>: ld s0,8(sp)
0xffffffff800040c2 <+52>: addi sp,sp,16
0xffffffff800040c4 <+54>: ret
We could see queued spinlock is better than ticket-lock when there is no
contend into queued_spin_lock_slowpath. And combo could provide a
compatible Linux Image for a different kind of micro-arch design.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 9 +++-
arch/riscv/include/asm/Kbuild | 1 -
arch/riscv/include/asm/spinlock.h | 77 +++++++++++++++++++++++++++++++
arch/riscv/kernel/setup.c | 22 +++++++++
4 files changed, 107 insertions(+), 2 deletions(-)
create mode 100644 arch/riscv/include/asm/spinlock.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 721f098228a8..f1d68491a1cf 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -361,7 +361,7 @@ config NODES_SHIFT
choice
prompt "RISC-V spinlock type"
- default RISCV_TICKET_SPINLOCKS
+ default RISCV_COMBO_SPINLOCKS
config RISCV_TICKET_SPINLOCKS
bool "Using ticket spinlock"
@@ -373,6 +373,13 @@ config RISCV_QUEUED_SPINLOCKS
help
Make sure your micro arch LL/SC has a strong forward progress guarantee.
Otherwise, stay at ticket-lock/combo-lock.
+
+config RISCV_COMBO_SPINLOCKS
+ bool "Using combo spinlock"
+ depends on SMP && MMU
+ select ARCH_USE_QUEUED_SPINLOCKS
+ help
+ Select queued spinlock or ticket-lock with jump_label.
endchoice
config RISCV_ALTERNATIVE
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 2cce98c7b653..59d5ea7390ea 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -5,7 +5,6 @@ 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
generic-y += qrwlock_types.h
diff --git a/arch/riscv/include/asm/spinlock.h b/arch/riscv/include/asm/spinlock.h
new file mode 100644
index 000000000000..b079462d818b
--- /dev/null
+++ b/arch/riscv/include/asm/spinlock.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_RISCV_SPINLOCK_H
+#define __ASM_RISCV_SPINLOCK_H
+
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+#include <asm-generic/ticket_spinlock.h>
+
+#undef arch_spin_is_locked
+#undef arch_spin_is_contended
+#undef arch_spin_value_unlocked
+#undef arch_spin_lock
+#undef arch_spin_trylock
+#undef arch_spin_unlock
+
+#include <asm-generic/qspinlock.h>
+#include <linux/jump_label.h>
+
+#undef arch_spin_is_locked
+#undef arch_spin_is_contended
+#undef arch_spin_value_unlocked
+#undef arch_spin_lock
+#undef arch_spin_trylock
+#undef arch_spin_unlock
+
+DECLARE_STATIC_KEY_TRUE(qspinlock_key);
+
+static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ queued_spin_lock(lock);
+ else
+ ticket_spin_lock(lock);
+}
+
+static __always_inline bool arch_spin_trylock(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_trylock(lock);
+ return ticket_spin_trylock(lock);
+}
+
+static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ queued_spin_unlock(lock);
+ else
+ ticket_spin_unlock(lock);
+}
+
+static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_value_unlocked(lock);
+ else
+ return ticket_spin_value_unlocked(lock);
+}
+
+static __always_inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_is_locked(lock);
+ return ticket_spin_is_locked(lock);
+}
+
+static __always_inline int arch_spin_is_contended(arch_spinlock_t *lock)
+{
+ if (static_branch_likely(&qspinlock_key))
+ return queued_spin_is_contended(lock);
+ return ticket_spin_is_contended(lock);
+}
+#include <asm/qrwlock.h>
+#else
+#include <asm-generic/spinlock.h>
+#endif /* CONFIG_RISCV_COMBO_SPINLOCKS */
+
+#endif /* __ASM_RISCV_SPINLOCK_H */
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index f0f36a4a0e9b..b763039bf49b 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -261,6 +261,13 @@ static void __init parse_dtb(void)
#endif
}
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+DEFINE_STATIC_KEY_TRUE_RO(qspinlock_key);
+EXPORT_SYMBOL(qspinlock_key);
+
+static bool qspinlock_flag __initdata = false;
+#endif
+
void __init setup_arch(char **cmdline_p)
{
parse_dtb();
@@ -295,10 +302,25 @@ void __init setup_arch(char **cmdline_p)
setup_smp();
#endif
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+ if (!qspinlock_flag)
+ static_branch_disable(&qspinlock_key);
+#endif
+
riscv_fill_hwcap();
apply_boot_alternatives();
}
+#ifdef CONFIG_RISCV_COMBO_SPINLOCKS
+static int __init enable_qspinlock(char *p)
+{
+ qspinlock_flag = true;
+
+ return 0;
+}
+early_param("qspinlock", enable_qspinlock);
+#endif
+
static int __init topology_init(void)
{
int i, ret;
--
2.36.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2022-07-24 12:26 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-24 12:25 [PATCH V8 00/10] arch: Add qspinlock support with combo style guoren
2022-07-24 12:25 ` guoren
2022-07-24 12:25 ` [PATCH V8 01/10] asm-generic: ticket-lock: Remove unnecessary atomic_read guoren
2022-07-24 12:25 ` guoren
2022-07-24 12:25 ` [PATCH V8 02/10] asm-generic: ticket-lock: Use the same struct definitions with qspinlock guoren
2022-07-24 12:25 ` guoren
2022-07-27 19:20 ` kernel test robot
2022-07-27 19:20 ` kernel test robot
2022-07-24 12:25 ` [PATCH V8 03/10] asm-generic: ticket-lock: Move into ticket_spinlock.h guoren
2022-07-24 12:25 ` guoren
2022-07-24 12:25 ` [PATCH V8 04/10] asm-generic: spinlock: Add queued spinlock support in common header guoren
2022-07-24 12:25 ` guoren
2022-07-24 12:25 ` [PATCH V8 05/10] riscv: Enable ARCH_INLINE_READ*/WRITE*/SPIN* guoren
2022-07-24 12:25 ` guoren
2022-07-24 12:25 ` [PATCH V8 06/10] riscv: atomic: Clean up unnecessary acquire and release definitions guoren
2022-07-24 12:25 ` guoren
2022-07-24 12:25 ` [PATCH V8 07/10] riscv: Add qspinlock support guoren
2022-07-24 12:25 ` guoren
2022-07-28 0:04 ` kernel test robot
2022-07-28 0:04 ` kernel test robot
2022-07-28 3:35 ` Guo Ren
2022-07-28 3:35 ` Guo Ren
2022-07-28 3:35 ` Guo Ren
2022-07-28 8:14 ` Arnd Bergmann
2022-07-28 8:14 ` Arnd Bergmann
2022-07-28 8:14 ` Arnd Bergmann
2022-07-28 8:34 ` Guo Ren
2022-07-28 8:34 ` Guo Ren
2022-07-28 8:34 ` Guo Ren
2022-07-24 12:25 ` guoren [this message]
2022-07-24 12:25 ` [PATCH V8 08/10] riscv: Add combo spinlock support guoren
2022-07-24 12:25 ` [PATCH V8 09/10] csky: Enable ARCH_INLINE_READ*/WRITE*/SPIN* guoren
2022-07-24 12:25 ` guoren
2022-07-24 12:25 ` [PATCH V8 10/10] csky: Add qspinlock support guoren
2022-07-24 12:25 ` guoren
2022-07-25 2:08 ` Waiman Long
2022-07-25 2:08 ` Waiman Long
2022-07-25 2:30 ` Guo Ren
2022-07-25 2:30 ` Guo Ren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220724122517.1019187-9-guoren@kernel.org \
--to=guoren@kernel.org \
--cc=David.Laight@ACULAB.COM \
--cc=arnd@arndb.de \
--cc=boqun.feng@gmail.com \
--cc=cmuellner@linux.com \
--cc=guoren@linux.alibaba.com \
--cc=hch@infradead.org \
--cc=heiko@sntech.de \
--cc=linux-csky@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=longman@redhat.com \
--cc=mingo@redhat.com \
--cc=palmer@rivosinc.com \
--cc=peterz@infradead.org \
--cc=philipp.tomsich@vrull.eu \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.