Messages in this thread Patch in this message | | | From | Nicholas Piggin <> | Subject | [PATCH v2 07/12] locking/qspinlock: remove arch qspinlock_paravirt.h includes | Date | Wed, 13 Jul 2022 17:06:59 +1000 |
| |
Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- arch/powerpc/include/asm/qspinlock_paravirt.h | 7 -- arch/x86/include/asm/qspinlock.h | 4 ++ arch/x86/include/asm/qspinlock_paravirt.h | 72 ------------------- arch/x86/kernel/paravirt-spinlocks.c | 71 ++++++++++++++++++ kernel/locking/qspinlock.c | 11 +-- 5 files changed, 76 insertions(+), 89 deletions(-) delete mode 100644 arch/powerpc/include/asm/qspinlock_paravirt.h delete mode 100644 arch/x86/include/asm/qspinlock_paravirt.h
diff --git a/arch/powerpc/include/asm/qspinlock_paravirt.h b/arch/powerpc/include/asm/qspinlock_paravirt.h deleted file mode 100644 index 6b60e7736a47..000000000000 --- a/arch/powerpc/include/asm/qspinlock_paravirt.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef _ASM_POWERPC_QSPINLOCK_PARAVIRT_H -#define _ASM_POWERPC_QSPINLOCK_PARAVIRT_H - -EXPORT_SYMBOL(__pv_queued_spin_unlock); - -#endif /* _ASM_POWERPC_QSPINLOCK_PARAVIRT_H */ diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h index d87451df480b..7f914fe7bc30 100644 --- a/arch/x86/include/asm/qspinlock.h +++ b/arch/x86/include/asm/qspinlock.h @@ -34,6 +34,10 @@ extern void __pv_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); extern void __raw_callee_save___pv_queued_spin_unlock(struct qspinlock *lock); extern bool nopvspin; +#ifdef CONFIG_64BIT +#define __pv_queued_spin_unlock __pv_queued_spin_unlock +#endif + #define queued_spin_unlock queued_spin_unlock /** * queued_spin_unlock - release a queued spinlock diff --git a/arch/x86/include/asm/qspinlock_paravirt.h b/arch/x86/include/asm/qspinlock_paravirt.h deleted file mode 100644 index 892fd8c3a6f7..000000000000 --- a/arch/x86/include/asm/qspinlock_paravirt.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __ASM_QSPINLOCK_PARAVIRT_H -#define __ASM_QSPINLOCK_PARAVIRT_H - -#include <asm/ibt.h> - -/* - * For x86-64, PV_CALLEE_SAVE_REGS_THUNK() saves and restores 8 64-bit - * registers. For i386, however, only 1 32-bit register needs to be saved - * and restored. So an optimized version of __pv_queued_spin_unlock() is - * hand-coded for 64-bit, but it isn't worthwhile to do it for 32-bit. - */ -#ifdef CONFIG_64BIT - -PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath); -#define __pv_queued_spin_unlock __pv_queued_spin_unlock -#define PV_UNLOCK "__raw_callee_save___pv_queued_spin_unlock" -#define PV_UNLOCK_SLOWPATH "__raw_callee_save___pv_queued_spin_unlock_slowpath" - -/* - * Optimized assembly version of __raw_callee_save___pv_queued_spin_unlock - * which combines the registers saving trunk and the body of the following - * C code: - * - * void __pv_queued_spin_unlock(struct qspinlock *lock) - * { - * u8 lockval = cmpxchg(&lock->locked, _Q_LOCKED_VAL, 0); - * - * if (likely(lockval == _Q_LOCKED_VAL)) - * return; - * pv_queued_spin_unlock_slowpath(lock, lockval); - * } - * - * For x86-64, - * rdi = lock (first argument) - * rsi = lockval (second argument) - * rdx = internal variable (set to 0) - */ -asm (".pushsection .text;" - ".globl " PV_UNLOCK ";" - ".type " PV_UNLOCK ", @function;" - ".align 4,0x90;" - PV_UNLOCK ": " - ASM_ENDBR - FRAME_BEGIN - "push %rdx;" - "mov $0x1,%eax;" - "xor %edx,%edx;" - LOCK_PREFIX "cmpxchg %dl,(%rdi);" - "cmp $0x1,%al;" - "jne .slowpath;" - "pop %rdx;" - FRAME_END - ASM_RET - ".slowpath: " - "push %rsi;" - "movzbl %al,%esi;" - "call " PV_UNLOCK_SLOWPATH ";" - "pop %rsi;" - "pop %rdx;" - FRAME_END - ASM_RET - ".size " PV_UNLOCK ", .-" PV_UNLOCK ";" - ".popsection"); - -#else /* CONFIG_64BIT */ - -extern void __pv_queued_spin_unlock(struct qspinlock *lock); -PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock); - -#endif /* CONFIG_64BIT */ -#endif diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 9e1ea99ad9df..c6a107dfe20d 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c @@ -7,6 +7,7 @@ #include <linux/export.h> #include <linux/jump_label.h> +#include <asm/ibt.h> #include <asm/paravirt.h> __visible void __native_queued_spin_unlock(struct qspinlock *lock) @@ -15,6 +16,76 @@ __visible void __native_queued_spin_unlock(struct qspinlock *lock) } PV_CALLEE_SAVE_REGS_THUNK(__native_queued_spin_unlock); +#ifdef CONFIG_PARAVIRT_SPINLOCKS +/* + * For x86-64, PV_CALLEE_SAVE_REGS_THUNK() saves and restores 8 64-bit + * registers. For i386, however, only 1 32-bit register needs to be saved + * and restored. So an optimized version of __pv_queued_spin_unlock() is + * hand-coded for 64-bit, but it isn't worthwhile to do it for 32-bit. + */ +#ifdef CONFIG_64BIT + +__visible void +__pv_queued_spin_unlock_slowpath(struct qspinlock *lock, u8 locked); + +PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath); +#define PV_UNLOCK "__raw_callee_save___pv_queued_spin_unlock" +#define PV_UNLOCK_SLOWPATH "__raw_callee_save___pv_queued_spin_unlock_slowpath" + +/* + * Optimized assembly version of __raw_callee_save___pv_queued_spin_unlock + * which combines the registers saving trunk and the body of the following + * C code: + * + * void __pv_queued_spin_unlock(struct qspinlock *lock) + * { + * u8 lockval = cmpxchg(&lock->locked, _Q_LOCKED_VAL, 0); + * + * if (likely(lockval == _Q_LOCKED_VAL)) + * return; + * pv_queued_spin_unlock_slowpath(lock, lockval); + * } + * + * For x86-64, + * rdi = lock (first argument) + * rsi = lockval (second argument) + * rdx = internal variable (set to 0) + */ +asm (".pushsection .text;" + ".globl " PV_UNLOCK ";" + ".type " PV_UNLOCK ", @function;" + ".align 4,0x90;" + PV_UNLOCK ": " + ASM_ENDBR + FRAME_BEGIN + "push %rdx;" + "mov $0x1,%eax;" + "xor %edx,%edx;" + LOCK_PREFIX "cmpxchg %dl,(%rdi);" + "cmp $0x1,%al;" + "jne .slowpath;" + "pop %rdx;" + FRAME_END + ASM_RET + ".slowpath: " + "push %rsi;" + "movzbl %al,%esi;" + "call " PV_UNLOCK_SLOWPATH ";" + "pop %rsi;" + "pop %rdx;" + FRAME_END + ASM_RET + ".size " PV_UNLOCK ", .-" PV_UNLOCK ";" + ".popsection"); + +#else /* CONFIG_64BIT */ + +extern void __pv_queued_spin_unlock(struct qspinlock *lock); +PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock); + +#endif /* CONFIG_64BIT */ +#endif /* CONFIG_PARAVIRT_SPINLOCKS */ + bool pv_is_native_spin_unlock(void) { return pv_ops.lock.queued_spin_unlock.func == diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c index 3b3663d15402..c4f223a03345 100644 --- a/kernel/locking/qspinlock.c +++ b/kernel/locking/qspinlock.c @@ -745,16 +745,6 @@ __pv_queued_spin_unlock_slowpath(struct qspinlock *lock, u8 locked) pv_kick(node->cpu); } -/* - * Include the architecture specific callee-save thunk of the - * __pv_queued_spin_unlock(). This thunk is put together with - * __pv_queued_spin_unlock() to make the callee-save thunk and the real unlock - * function close to each other sharing consecutive instruction cachelines. - * Alternatively, architecture specific version of __pv_queued_spin_unlock() - * can be defined. - */ -#include <asm/qspinlock_paravirt.h> - #ifndef __pv_queued_spin_unlock __visible void __pv_queued_spin_unlock(struct qspinlock *lock) { @@ -771,6 +761,7 @@ __visible void __pv_queued_spin_unlock(struct qspinlock *lock) __pv_queued_spin_unlock_slowpath(lock, locked); } +EXPORT_SYMBOL(__pv_queued_spin_unlock); #endif #else /* CONFIG_PARAVIRT_SPINLOCKS */ -- 2.35.1
| |