/* SPDX-License-Identifier: GPL-2.0-or-later */1/*2* Queued spinlock defines3*4* This file contains macro definitions and functions shared between different5* qspinlock slow path implementations.6*/7#ifndef __LINUX_QSPINLOCK_H8#define __LINUX_QSPINLOCK_H910#include <asm-generic/percpu.h>11#include <linux/percpu-defs.h>12#include <asm-generic/qspinlock.h>13#include <asm-generic/mcs_spinlock.h>1415#define _Q_MAX_NODES 41617/*18* The pending bit spinning loop count.19* This heuristic is used to limit the number of lockword accesses20* made by atomic_cond_read_relaxed when waiting for the lock to21* transition out of the "== _Q_PENDING_VAL" state. We don't spin22* indefinitely because there's no guarantee that we'll make forward23* progress.24*/25#ifndef _Q_PENDING_LOOPS26#define _Q_PENDING_LOOPS 127#endif2829/*30* On 64-bit architectures, the mcs_spinlock structure will be 16 bytes in31* size and four of them will fit nicely in one 64-byte cacheline. For32* pvqspinlock, however, we need more space for extra data. To accommodate33* that, we insert two more long words to pad it up to 32 bytes. IOW, only34* two of them can fit in a cacheline in this case. That is OK as it is rare35* to have more than 2 levels of slowpath nesting in actual use. We don't36* want to penalize pvqspinlocks to optimize for a rare case in native37* qspinlocks.38*/39struct qnode {40struct mcs_spinlock mcs;41#ifdef CONFIG_PARAVIRT_SPINLOCKS42long reserved[2];43#endif44};4546/*47* We must be able to distinguish between no-tail and the tail at 0:0,48* therefore increment the cpu number by one.49*/5051static inline __pure u32 encode_tail(int cpu, int idx)52{53u32 tail;5455tail = (cpu + 1) << _Q_TAIL_CPU_OFFSET;56tail |= idx << _Q_TAIL_IDX_OFFSET; /* assume < 4 */5758return tail;59}6061static inline __pure struct mcs_spinlock *decode_tail(u32 tail,62struct qnode __percpu *qnodes)63{64int cpu = (tail >> _Q_TAIL_CPU_OFFSET) - 1;65int idx = (tail & _Q_TAIL_IDX_MASK) >> _Q_TAIL_IDX_OFFSET;6667return per_cpu_ptr(&qnodes[idx].mcs, cpu);68}6970static inline __pure71struct mcs_spinlock *grab_mcs_node(struct mcs_spinlock *base, int idx)72{73return &((struct qnode *)base + idx)->mcs;74}7576#define _Q_LOCKED_PENDING_MASK (_Q_LOCKED_MASK | _Q_PENDING_MASK)7778#if _Q_PENDING_BITS == 879/**80* clear_pending - clear the pending bit.81* @lock: Pointer to queued spinlock structure82*83* *,1,* -> *,0,*84*/85static __always_inline void clear_pending(struct qspinlock *lock)86{87WRITE_ONCE(lock->pending, 0);88}8990/**91* clear_pending_set_locked - take ownership and clear the pending bit.92* @lock: Pointer to queued spinlock structure93*94* *,1,0 -> *,0,195*96* Lock stealing is not allowed if this function is used.97*/98static __always_inline void clear_pending_set_locked(struct qspinlock *lock)99{100WRITE_ONCE(lock->locked_pending, _Q_LOCKED_VAL);101}102103/*104* xchg_tail - Put in the new queue tail code word & retrieve previous one105* @lock : Pointer to queued spinlock structure106* @tail : The new queue tail code word107* Return: The previous queue tail code word108*109* xchg(lock, tail), which heads an address dependency110*111* p,*,* -> n,*,* ; prev = xchg(lock, node)112*/113static __always_inline u32 xchg_tail(struct qspinlock *lock, u32 tail)114{115/*116* We can use relaxed semantics since the caller ensures that the117* MCS node is properly initialized before updating the tail.118*/119return (u32)xchg_relaxed(&lock->tail,120tail >> _Q_TAIL_OFFSET) << _Q_TAIL_OFFSET;121}122123#else /* _Q_PENDING_BITS == 8 */124125/**126* clear_pending - clear the pending bit.127* @lock: Pointer to queued spinlock structure128*129* *,1,* -> *,0,*130*/131static __always_inline void clear_pending(struct qspinlock *lock)132{133atomic_andnot(_Q_PENDING_VAL, &lock->val);134}135136/**137* clear_pending_set_locked - take ownership and clear the pending bit.138* @lock: Pointer to queued spinlock structure139*140* *,1,0 -> *,0,1141*/142static __always_inline void clear_pending_set_locked(struct qspinlock *lock)143{144atomic_add(-_Q_PENDING_VAL + _Q_LOCKED_VAL, &lock->val);145}146147/**148* xchg_tail - Put in the new queue tail code word & retrieve previous one149* @lock : Pointer to queued spinlock structure150* @tail : The new queue tail code word151* Return: The previous queue tail code word152*153* xchg(lock, tail)154*155* p,*,* -> n,*,* ; prev = xchg(lock, node)156*/157static __always_inline u32 xchg_tail(struct qspinlock *lock, u32 tail)158{159u32 old, new;160161old = atomic_read(&lock->val);162do {163new = (old & _Q_LOCKED_PENDING_MASK) | tail;164/*165* We can use relaxed semantics since the caller ensures that166* the MCS node is properly initialized before updating the167* tail.168*/169} while (!atomic_try_cmpxchg_relaxed(&lock->val, &old, new));170171return old;172}173#endif /* _Q_PENDING_BITS == 8 */174175/**176* queued_fetch_set_pending_acquire - fetch the whole lock value and set pending177* @lock : Pointer to queued spinlock structure178* Return: The previous lock value179*180* *,*,* -> *,1,*181*/182#ifndef queued_fetch_set_pending_acquire183static __always_inline u32 queued_fetch_set_pending_acquire(struct qspinlock *lock)184{185return atomic_fetch_or_acquire(_Q_PENDING_VAL, &lock->val);186}187#endif188189/**190* set_locked - Set the lock bit and own the lock191* @lock: Pointer to queued spinlock structure192*193* *,*,0 -> *,0,1194*/195static __always_inline void set_locked(struct qspinlock *lock)196{197WRITE_ONCE(lock->locked, _Q_LOCKED_VAL);198}199200#endif /* __LINUX_QSPINLOCK_H */201202203