@@ -6,4 +6,9 @@
#include <asm-generic/ticket_spinlock.h>
#include <asm/qrwlock.h>
+/* See include/linux/spinlock.h */
+#ifndef smp_mb__after_spinlock
+#define smp_mb__after_spinlock() smp_mb()
+#endif
+
#endif /* __ASM_GENERIC_SPINLOCK_H */
@@ -14,9 +14,8 @@
* a test-and-set.
*
* It further assumes atomic_*_release() + atomic_*_acquire() is RCpc and hence
- * uses atomic_fetch_add() which is RCsc to create an RCsc hot path, along with
- * a full fence after the spin to upgrade the otherwise-RCpc
- * atomic_cond_read_acquire().
+ * uses smp_mb__after_spinlock which is RCsc to create an RCsc hot path, See
+ * include/linux/spinlock.h
*
* The implementation uses smp_cond_load_acquire() to spin, so if the
* architecture has WFE like instructions to sleep instead of poll for word
@@ -32,22 +31,13 @@
static __always_inline void ticket_spin_lock(arch_spinlock_t *lock)
{
- u32 val = atomic_fetch_add(1<<16, &lock->val);
+ u32 val = atomic_fetch_add_acquire(1<<16, &lock->val);
u16 ticket = val >> 16;
if (ticket == (u16)val)
return;
- /*
- * atomic_cond_read_acquire() is RCpc, but rather than defining a
- * custom cond_read_rcsc() here we just emit a full fence. We only
- * need the prior reads before subsequent writes ordering from
- * smb_mb(), but as atomic_cond_read_acquire() just emits reads and we
- * have no outstanding writes due to the atomic_fetch_add() the extra
- * orderings are free.
- */
atomic_cond_read_acquire(&lock->val, ticket == (u16)VAL);
- smp_mb();
}
static __always_inline bool ticket_spin_trylock(arch_spinlock_t *lock)
@@ -57,7 +47,7 @@ static __always_inline bool ticket_spin_trylock(arch_spinlock_t *lock)
if ((old >> 16) != (old & 0xffff))
return false;
- return atomic_try_cmpxchg(&lock->val, &old, old + (1<<16)); /* SC, for RCsc */
+ return atomic_try_cmpxchg_acquire(&lock->val, &old, old + (1<<16));
}
static __always_inline void ticket_spin_unlock(arch_spinlock_t *lock)