diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2024-11-26 14:28:27 +0100 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2024-11-28 14:14:34 +0100 |
commit | 889221c4d78d754023bec8edec13d11a13b3fb51 (patch) | |
tree | a24da4365500394d1b004dfd1d50fadaab94b620 /arch | |
parent | 84ac96587b2a7a27d2aba250009c45dffb8ab4b6 (diff) | |
download | lwn-889221c4d78d754023bec8edec13d11a13b3fb51.tar.gz lwn-889221c4d78d754023bec8edec13d11a13b3fb51.zip |
s390/spinlock: Use flag output constraint for arch_cmpxchg_niai8()
Add a new variant of arch_cmpxchg_niai8() which makes use of the flag
output constraint, which allows the compiler to generate slightly better
code. Also rename arch_cmpxchg_niai8() to arch_try_cmpxchg_niai8() which
reflects the purpose of the function and makes it consistent with other
"try" variants.
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/lib/spinlock.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index c27c0f2a8018..a81a01c44927 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -15,6 +15,7 @@ #include <linux/percpu.h> #include <linux/io.h> #include <asm/alternative.h> +#include <asm/asm.h> int spin_retry = -1; @@ -81,7 +82,24 @@ static inline int arch_load_niai4(int *lock) return owner; } -static inline int arch_cmpxchg_niai8(int *lock, int old, int new) +#ifdef __HAVE_ASM_FLAG_OUTPUTS__ + +static inline int arch_try_cmpxchg_niai8(int *lock, int old, int new) +{ + int cc; + + asm_inline volatile( + ALTERNATIVE("nop", ".insn rre,0xb2fa0000,8,0", ALT_FACILITY(49)) /* NIAI 8 */ + " cs %[old],%[new],%[lock]\n" + : [old] "+d" (old), [lock] "+Q" (*lock), "=@cc" (cc) + : [new] "d" (new) + : "memory"); + return cc == 0; +} + +#else /* __HAVE_ASM_FLAG_OUTPUTS__ */ + +static inline int arch_try_cmpxchg_niai8(int *lock, int old, int new) { int expected = old; @@ -94,6 +112,8 @@ static inline int arch_cmpxchg_niai8(int *lock, int old, int new) return expected == old; } +#endif /* __HAVE_ASM_FLAG_OUTPUTS__ */ + static inline struct spin_wait *arch_spin_decode_tail(int lock) { int ix, cpu; @@ -226,7 +246,7 @@ static inline void arch_spin_lock_classic(arch_spinlock_t *lp) /* Try to get the lock if it is free. */ if (!owner) { new = (old & _Q_TAIL_MASK) | lockval; - if (arch_cmpxchg_niai8(&lp->lock, old, new)) { + if (arch_try_cmpxchg_niai8(&lp->lock, old, new)) { /* Got the lock */ return; } |