qspinlock.h (2064B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _ASM_POWERPC_QSPINLOCK_H 3#define _ASM_POWERPC_QSPINLOCK_H 4 5#include <asm-generic/qspinlock_types.h> 6#include <asm/paravirt.h> 7 8#define _Q_PENDING_LOOPS (1 << 9) /* not tuned */ 9 10#ifdef CONFIG_PARAVIRT_SPINLOCKS 11extern void native_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); 12extern void __pv_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); 13extern void __pv_queued_spin_unlock(struct qspinlock *lock); 14 15static __always_inline void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val) 16{ 17 if (!is_shared_processor()) 18 native_queued_spin_lock_slowpath(lock, val); 19 else 20 __pv_queued_spin_lock_slowpath(lock, val); 21} 22 23#define queued_spin_unlock queued_spin_unlock 24static inline void queued_spin_unlock(struct qspinlock *lock) 25{ 26 if (!is_shared_processor()) 27 smp_store_release(&lock->locked, 0); 28 else 29 __pv_queued_spin_unlock(lock); 30} 31 32#else 33extern void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); 34#endif 35 36static __always_inline void queued_spin_lock(struct qspinlock *lock) 37{ 38 u32 val = 0; 39 40 if (likely(arch_atomic_try_cmpxchg_lock(&lock->val, &val, _Q_LOCKED_VAL))) 41 return; 42 43 queued_spin_lock_slowpath(lock, val); 44} 45#define queued_spin_lock queued_spin_lock 46 47#ifdef CONFIG_PARAVIRT_SPINLOCKS 48#define SPIN_THRESHOLD (1<<15) /* not tuned */ 49 50static __always_inline void pv_wait(u8 *ptr, u8 val) 51{ 52 if (*ptr != val) 53 return; 54 yield_to_any(); 55 /* 56 * We could pass in a CPU here if waiting in the queue and yield to 57 * the previous CPU in the queue. 58 */ 59} 60 61static __always_inline void pv_kick(int cpu) 62{ 63 prod_cpu(cpu); 64} 65 66extern void __pv_init_lock_hash(void); 67 68static inline void pv_spinlocks_init(void) 69{ 70 __pv_init_lock_hash(); 71} 72 73#endif 74 75/* 76 * Queued spinlocks rely heavily on smp_cond_load_relaxed() to busy-wait, 77 * which was found to have performance problems if implemented with 78 * the preferred spin_begin()/spin_end() SMT priority pattern. Use the 79 * generic version instead. 80 */ 81 82#include <asm-generic/qspinlock.h> 83 84#endif /* _ASM_POWERPC_QSPINLOCK_H */