Commit 4c93c2e4 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/qspinlock: use a half-word store to unlock to avoid larx/stcx.



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: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20221126095932.1234527-3-npiggin@gmail.com
parent 84990b16
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -37,11 +37,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)
+17 −2
Original line number Diff line number Diff line
@@ -3,12 +3,27 @@
#define _ASM_POWERPC_QSPINLOCK_TYPES_H

#include <linux/types.h>
#include <asm/byteorder.h>

typedef struct qspinlock {
	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: