rwsem.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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_RWSEM_SPIN_ON_OWNER
  19. /*
  20. * All writes to owner are protected by WRITE_ONCE() to make sure that
  21. * store tearing can't happen as optimistic spinners may read and use
  22. * the owner value concurrently without lock. Read from owner, however,
  23. * may not need READ_ONCE() as long as the pointer value is only used
  24. * for comparison and isn't being dereferenced.
  25. */
  26. static inline void rwsem_set_owner(struct rw_semaphore *sem)
  27. {
  28. WRITE_ONCE(sem->owner, current);
  29. }
  30. static inline void rwsem_clear_owner(struct rw_semaphore *sem)
  31. {
  32. WRITE_ONCE(sem->owner, NULL);
  33. }
  34. static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
  35. {
  36. /*
  37. * We check the owner value first to make sure that we will only
  38. * do a write to the rwsem cacheline when it is really necessary
  39. * to minimize cacheline contention.
  40. */
  41. if (sem->owner != RWSEM_READER_OWNED)
  42. WRITE_ONCE(sem->owner, RWSEM_READER_OWNED);
  43. }
  44. static inline bool rwsem_owner_is_writer(struct task_struct *owner)
  45. {
  46. return owner && owner != RWSEM_READER_OWNED;
  47. }
  48. static inline bool rwsem_owner_is_reader(struct task_struct *owner)
  49. {
  50. return owner == RWSEM_READER_OWNED;
  51. }
  52. #else
  53. static inline void rwsem_set_owner(struct rw_semaphore *sem)
  54. {
  55. }
  56. static inline void rwsem_clear_owner(struct rw_semaphore *sem)
  57. {
  58. }
  59. static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
  60. {
  61. }
  62. #endif