Commit 77a60e75 authored by Waiman Long's avatar Waiman Long Committed by Greg Kroah-Hartman

locking/percpu-rwsem: Annotate rwsem ownership transfer by setting RWSEM_OWNER_UNKNOWN

[ Upstream commit 5a817641 ]

The filesystem freezing code needs to transfer ownership of a rwsem
embedded in a percpu-rwsem from the task that does the freezing to
another one that does the thawing by calling percpu_rwsem_release()
after freezing and percpu_rwsem_acquire() before thawing.

However, the new rwsem debug code runs afoul with this scheme by warning
that the task that releases the rwsem isn't the one that acquires it,
as reported by Amir Goldstein:

  DEBUG_LOCKS_WARN_ON(sem->owner != get_current())
  WARNING: CPU: 1 PID: 1401 at /home/amir/build/src/linux/kernel/locking/rwsem.c:133 up_write+0x59/0x79

  Call Trace:

To work properly with the rwsem debug code, we need to annotate that the
rwsem ownership is unknown during the tranfer period until a brave soul
comes forward to acquire the ownership. During that period, optimistic
spinning will be disabled.
Reported-by: default avatarAmir Goldstein <>
Tested-by: default avatarAmir Goldstein <>
Signed-off-by: default avatarWaiman Long <>
Acked-by: default avatarPeter Zijlstra <>
Cc: Andrew Morton <>
Cc: Davidlohr Bueso <>
Cc: Jan Kara <>
Cc: Linus Torvalds <>
Cc: Matthew Wilcox <>
Cc: Oleg Nesterov <>
Cc: Paul E. McKenney <>
Cc: Theodore Y. Ts'o <>
Cc: Thomas Gleixner <>
Cc: Will Deacon <>
Link: default avatarIngo Molnar <>
Signed-off-by: default avatarSasha Levin <>
Signed-off-by: default avatarGreg Kroah-Hartman <>
parent b3f84e48
......@@ -133,7 +133,7 @@ static inline void percpu_rwsem_release(struct percpu_rw_semaphore *sem,
lock_release(&sem->rw_sem.dep_map, 1, ip);
if (!read)
sem->rw_sem.owner = NULL;
sem->rw_sem.owner = RWSEM_OWNER_UNKNOWN;
......@@ -141,6 +141,10 @@ static inline void percpu_rwsem_acquire(struct percpu_rw_semaphore *sem,
bool read, unsigned long ip)
lock_acquire(&sem->rw_sem.dep_map, 0, 1, read, 1, NULL, ip);
if (!read)
sem->rw_sem.owner = current;
......@@ -44,6 +44,12 @@ struct rw_semaphore {
* Setting bit 0 of the owner field with other non-zero bits will indicate
* that the rwsem is writer-owned with an unknown owner.
#define RWSEM_OWNER_UNKNOWN ((struct task_struct *)-1L)
extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_down_read_failed_killable(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
......@@ -352,6 +352,8 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem)
struct task_struct *owner;
bool ret = true;
if (need_resched())
return false;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment