rwsem.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * The owner field of the rw_semaphore structure will be set to
  4. * RWSEM_READ_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 3 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) Other non-zero value
  15. * - a writer owns the lock
  16. */
  17. #define RWSEM_READER_OWNED ((struct task_struct *)1UL)
  18. #ifdef CONFIG_DEBUG_RWSEMS
  19. # define DEBUG_RWSEMS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c)
  20. #else
  21. # define DEBUG_RWSEMS_WARN_ON(c)
  22. #endif
  23. #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
  24. /*
  25. * All writes to owner are protected by WRITE_ONCE() to make sure that
  26. * store tearing can't happen as optimistic spinners may read and use
  27. * the owner value concurrently without lock. Read from owner, however,
  28. * may not need READ_ONCE() as long as the pointer value is only used
  29. * for comparison and isn't being dereferenced.
  30. */
  31. static inline void rwsem_set_owner(struct rw_semaphore *sem)
  32. {
  33. WRITE_ONCE(sem->owner, current);
  34. }
  35. static inline void rwsem_clear_owner(struct rw_semaphore *sem)
  36. {
  37. WRITE_ONCE(sem->owner, NULL);
  38. }
  39. static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
  40. {
  41. /*
  42. * We check the owner value first to make sure that we will only
  43. * do a write to the rwsem cacheline when it is really necessary
  44. * to minimize cacheline contention.
  45. */
  46. if (READ_ONCE(sem->owner) != RWSEM_READER_OWNED)
  47. WRITE_ONCE(sem->owner, RWSEM_READER_OWNED);
  48. }
  49. static inline bool rwsem_owner_is_writer(struct task_struct *owner)
  50. {
  51. return owner && owner != RWSEM_READER_OWNED;
  52. }
  53. static inline bool rwsem_owner_is_reader(struct task_struct *owner)
  54. {
  55. return owner == RWSEM_READER_OWNED;
  56. }
  57. #else
  58. static inline void rwsem_set_owner(struct rw_semaphore *sem)
  59. {
  60. }
  61. static inline void rwsem_clear_owner(struct rw_semaphore *sem)
  62. {
  63. }
  64. static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
  65. {
  66. }
  67. #endif