rwsem.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * The owner field of the rw_semaphore structure will be set to
  4. * RWSEM_READER_OWNED when a reader grabs the lock. A writer will clear
  5. * the owner field when it unlocks. A reader, on the other hand, will
  6. * not touch the owner field when it unlocks.
  7. *
  8. * In essence, the owner field now has the following 4 states:
  9. * 1) 0
  10. * - lock is free or the owner hasn't set the field yet
  11. * 2) RWSEM_READER_OWNED
  12. * - lock is currently or previously owned by readers (lock is free
  13. * or not set by owner yet)
  14. * 3) RWSEM_ANONYMOUSLY_OWNED bit set with some other bits set as well
  15. * - lock is owned by an anonymous writer, so spinning on the lock
  16. * owner should be disabled.
  17. * 4) Other non-zero value
  18. * - a writer owns the lock and other writers can spin on the lock owner.
  19. */
  20. #define RWSEM_ANONYMOUSLY_OWNED (1UL << 0)
  21. #define RWSEM_READER_OWNED ((struct task_struct *)RWSEM_ANONYMOUSLY_OWNED)
  22. #ifdef CONFIG_DEBUG_RWSEMS
  23. # define DEBUG_RWSEMS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c)
  24. #else
  25. # define DEBUG_RWSEMS_WARN_ON(c)
  26. #endif
  27. #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
  28. /*
  29. * All writes to owner are protected by WRITE_ONCE() to make sure that
  30. * store tearing can't happen as optimistic spinners may read and use
  31. * the owner value concurrently without lock. Read from owner, however,
  32. * may not need READ_ONCE() as long as the pointer value is only used
  33. * for comparison and isn't being dereferenced.
  34. */
  35. static inline void rwsem_set_owner(struct rw_semaphore *sem)
  36. {
  37. WRITE_ONCE(sem->owner, current);
  38. }
  39. static inline void rwsem_clear_owner(struct rw_semaphore *sem)
  40. {
  41. WRITE_ONCE(sem->owner, NULL);
  42. }
  43. static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
  44. {
  45. /*
  46. * We check the owner value first to make sure that we will only
  47. * do a write to the rwsem cacheline when it is really necessary
  48. * to minimize cacheline contention.
  49. */
  50. if (READ_ONCE(sem->owner) != RWSEM_READER_OWNED)
  51. WRITE_ONCE(sem->owner, RWSEM_READER_OWNED);
  52. }
  53. /*
  54. * Return true if the a rwsem waiter can spin on the rwsem's owner
  55. * and steal the lock, i.e. the lock is not anonymously owned.
  56. * N.B. !owner is considered spinnable.
  57. */
  58. static inline bool is_rwsem_owner_spinnable(struct task_struct *owner)
  59. {
  60. return !((unsigned long)owner & RWSEM_ANONYMOUSLY_OWNED);
  61. }
  62. /*
  63. * Return true if rwsem is owned by an anonymous writer or readers.
  64. */
  65. static inline bool rwsem_has_anonymous_owner(struct task_struct *owner)
  66. {
  67. return (unsigned long)owner & RWSEM_ANONYMOUSLY_OWNED;
  68. }
  69. #else
  70. static inline void rwsem_set_owner(struct rw_semaphore *sem)
  71. {
  72. }
  73. static inline void rwsem_clear_owner(struct rw_semaphore *sem)
  74. {
  75. }
  76. static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
  77. {
  78. }
  79. #endif