qspinlock.h 913 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_LOONGARCH_QSPINLOCK_H
  3. #define _ASM_LOONGARCH_QSPINLOCK_H
  4. #include <linux/jump_label.h>
  5. #ifdef CONFIG_PARAVIRT
  6. DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key);
  7. #define virt_spin_lock virt_spin_lock
  8. static inline bool virt_spin_lock(struct qspinlock *lock)
  9. {
  10. int val;
  11. if (!static_branch_unlikely(&virt_spin_lock_key))
  12. return false;
  13. /*
  14. * On hypervisors without PARAVIRT_SPINLOCKS support we fall
  15. * back to a Test-and-Set spinlock, because fair locks have
  16. * horrible lock 'holder' preemption issues.
  17. */
  18. __retry:
  19. val = atomic_read(&lock->val);
  20. if (val || !atomic_try_cmpxchg(&lock->val, &val, _Q_LOCKED_VAL)) {
  21. cpu_relax();
  22. goto __retry;
  23. }
  24. return true;
  25. }
  26. #define vcpu_is_preempted vcpu_is_preempted
  27. bool vcpu_is_preempted(int cpu);
  28. #endif /* CONFIG_PARAVIRT */
  29. #include <asm-generic/qspinlock.h>
  30. #endif // _ASM_LOONGARCH_QSPINLOCK_H