public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] locking/rwsem: Fix lock optimistic spinning when owner is not running
@ 2015-03-07  7:45 Jason Low
  2015-03-07  9:21 ` Peter Zijlstra
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Jason Low @ 2015-03-07  7:45 UTC (permalink / raw)
  To: Linus Torvalds, Ingo Molnar, Peter Zijlstra
  Cc: Davidlohr Bueso, Tim Chen, Paul E. McKenney, Michel Lespinasse,
	Sasha Levin, LKML, Dave Jones, Ming Lei, Jason Low

Fixes tip commit b3fd4f03ca0b (locking/rwsem: Avoid deceiving lock spinners).

Ming reported soft lockups occurring when running xfstest due to
commit b3fd4f03ca0b.

When doing optimistic spinning in rwsem, threads should stop spinning when
the lock owner is not running. While a thread is spinning on owner, if
the owner reschedules, owner->on_cpu returns false and we stop spinning.

However, commit b3fd4f03ca0b essentially caused the check to get ignored
because when we break out of the spin loop due to !on_cpu, we continue
spinning if sem->owner != NULL.

This patch fixes this by making sure we stop spinning if the owner is not
running. Furthermore, just like with mutexes, refactor the code such that
we don't have separate checks for owner_running(). This makes it more
straightforward in terms of why we exit the spin on owner loop and we
would also avoid needing to "guess" why we broke out of the loop to make
this more readable.

Reported-and-tested-by: Ming Lei <ming.lei@canonical.com>
Acked-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Jason Low <jason.low2@hp.com>
---
 kernel/locking/rwsem-xadd.c |   31 +++++++++++--------------------
 1 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c
index 06e2214..3417d01 100644
--- a/kernel/locking/rwsem-xadd.c
+++ b/kernel/locking/rwsem-xadd.c
@@ -324,32 +324,23 @@ done:
 	return ret;
 }
 
-static inline bool owner_running(struct rw_semaphore *sem,
-				 struct task_struct *owner)
-{
-	if (sem->owner != owner)
-		return false;
-
-	/*
-	 * Ensure we emit the owner->on_cpu, dereference _after_ checking
-	 * sem->owner still matches owner, if that fails, owner might
-	 * point to free()d memory, if it still matches, the rcu_read_lock()
-	 * ensures the memory stays valid.
-	 */
-	barrier();
-
-	return owner->on_cpu;
-}
-
 static noinline
 bool rwsem_spin_on_owner(struct rw_semaphore *sem, struct task_struct *owner)
 {
 	long count;
 
 	rcu_read_lock();
-	while (owner_running(sem, owner)) {
-		/* abort spinning when need_resched */
-		if (need_resched()) {
+	while (sem->owner == owner) {
+		/*
+		 * Ensure we emit the owner->on_cpu, dereference _after_
+		 * checking sem->owner still matches owner, if that fails,
+		 * owner might point to free()d memory, if it still matches,
+		 * the rcu_read_lock() ensures the memory stays valid.
+		 */
+		barrier();
+
+		/* abort spinning when need_resched or owner is not running */
+		if (!owner->on_cpu || need_resched()) {
 			rcu_read_unlock();
 			return false;
 		}
-- 
1.7.2.5




^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-03-10 18:35 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-07  7:45 [PATCH] locking/rwsem: Fix lock optimistic spinning when owner is not running Jason Low
2015-03-07  9:21 ` Peter Zijlstra
2015-03-09 17:42   ` Jason Low
2015-03-07 16:43 ` [tip:locking/core] " tip-bot for Jason Low
2015-03-07 17:13   ` Oleg Nesterov
2015-03-10 10:59     ` Peter Zijlstra
2015-03-10 16:04     ` Linus Torvalds
2015-03-10 16:16       ` Peter Zijlstra
2015-03-10 17:28       ` Oleg Nesterov
2015-03-10 17:45         ` Linus Torvalds
2015-03-10 18:33           ` Oleg Nesterov
2015-03-07 18:17 ` [PATCH] " Sasha Levin
2015-03-09 17:37   ` Jason Low

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox