The first 16 bits of the lock are only modified by the owner, and other
modifications always use atomic operations on the entire 32 bits, so
unlocks can use plain stores on the 16 bits. This is the same kind of
optimisation done by core qspinlock code.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/include/asm/qspinlock.h       |  6 +-----
 arch/powerpc/include/asm/qspinlock_types.h | 19 +++++++++++++++++--
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/qspinlock.h 
b/arch/powerpc/include/asm/qspinlock.h
index 300c7d2ebe2e..7bc254c55705 100644
--- a/arch/powerpc/include/asm/qspinlock.h
+++ b/arch/powerpc/include/asm/qspinlock.h
@@ -36,11 +36,7 @@ static __always_inline void queued_spin_lock(struct 
qspinlock *lock)
 
 static inline void queued_spin_unlock(struct qspinlock *lock)
 {
-       for (;;) {
-               int val = atomic_read(&lock->val);
-               if (atomic_cmpxchg_release(&lock->val, val, val & 
~_Q_LOCKED_VAL) == val)
-                       return;
-       }
+       smp_store_release(&lock->locked, 0);
 }
 
 #define arch_spin_is_locked(l)         queued_spin_is_locked(l)
diff --git a/arch/powerpc/include/asm/qspinlock_types.h 
b/arch/powerpc/include/asm/qspinlock_types.h
index 20a36dfb14e2..fe87181c59e5 100644
--- a/arch/powerpc/include/asm/qspinlock_types.h
+++ b/arch/powerpc/include/asm/qspinlock_types.h
@@ -3,12 +3,27 @@
 #define _ASM_POWERPC_QSPINLOCK_TYPES_H
 
 #include <linux/types.h>
+#include <asm/byteorder.h>
 
 typedef struct qspinlock {
-       atomic_t val;
+       union {
+               atomic_t val;
+
+#ifdef __LITTLE_ENDIAN
+               struct {
+                       u16     locked;
+                       u8      reserved[2];
+               };
+#else
+               struct {
+                       u8      reserved[2];
+                       u16     locked;
+               };
+#endif
+       };
 } arch_spinlock_t;
 
-#define        __ARCH_SPIN_LOCK_UNLOCKED       { .val = ATOMIC_INIT(0) }
+#define        __ARCH_SPIN_LOCK_UNLOCKED       { { .val = ATOMIC_INIT(0) } }
 
 /*
  * Bitfields in the lock word:
-- 
2.37.2

Reply via email to