qspinlock.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #ifndef _ASM_X86_QSPINLOCK_H
  2. #define _ASM_X86_QSPINLOCK_H
  3. #include <asm/cpufeature.h>
  4. #include <asm-generic/qspinlock_types.h>
  5. #include <asm/paravirt.h>
  6. #define queued_spin_unlock queued_spin_unlock
  7. /**
  8. * queued_spin_unlock - release a queued spinlock
  9. * @lock : Pointer to queued spinlock structure
  10. *
  11. * A smp_store_release() on the least-significant byte.
  12. */
  13. static inline void native_queued_spin_unlock(struct qspinlock *lock)
  14. {
  15. smp_store_release((u8 *)lock, 0);
  16. }
  17. #ifdef CONFIG_PARAVIRT_SPINLOCKS
  18. extern void native_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
  19. extern void __pv_init_lock_hash(void);
  20. extern void __pv_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
  21. extern void __raw_callee_save___pv_queued_spin_unlock(struct qspinlock *lock);
  22. static inline void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
  23. {
  24. pv_queued_spin_lock_slowpath(lock, val);
  25. }
  26. static inline void queued_spin_unlock(struct qspinlock *lock)
  27. {
  28. pv_queued_spin_unlock(lock);
  29. }
  30. #else
  31. static inline void queued_spin_unlock(struct qspinlock *lock)
  32. {
  33. native_queued_spin_unlock(lock);
  34. }
  35. #endif
  36. #ifdef CONFIG_PARAVIRT
  37. #define virt_spin_lock virt_spin_lock
  38. static inline bool virt_spin_lock(struct qspinlock *lock)
  39. {
  40. if (!static_cpu_has(X86_FEATURE_HYPERVISOR))
  41. return false;
  42. /*
  43. * On hypervisors without PARAVIRT_SPINLOCKS support we fall
  44. * back to a Test-and-Set spinlock, because fair locks have
  45. * horrible lock 'holder' preemption issues.
  46. */
  47. do {
  48. while (atomic_read(&lock->val) != 0)
  49. cpu_relax();
  50. } while (atomic_cmpxchg(&lock->val, 0, _Q_LOCKED_VAL) != 0);
  51. return true;
  52. }
  53. #endif /* CONFIG_PARAVIRT */
  54. #include <asm-generic/qspinlock.h>
  55. #endif /* _ASM_X86_QSPINLOCK_H */