From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751525AbbCGQol (ORCPT ); Sat, 7 Mar 2015 11:44:41 -0500 Received: from terminus.zytor.com ([198.137.202.10]:46358 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751300AbbCGQod (ORCPT ); Sat, 7 Mar 2015 11:44:33 -0500 Date: Sat, 7 Mar 2015 08:43:18 -0800 From: tip-bot for Jason Low Message-ID: Cc: dave@stgolabs.net, hpa@zytor.com, sasha.levin@oracle.com, oleg@redhat.com, tglx@linutronix.de, linux-kernel@vger.kernel.org, jason.low2@hp.com, walken@google.com, akpm@linux-foundation.org, mingo@kernel.org, paulmck@linux.vnet.ibm.com, davej@codemonkey.org.uk, ming.lei@canonical.com, peterz@infradead.org, torvalds@linux-foundation.org, tim.c.chen@linux.intel.com Reply-To: ming.lei@canonical.com, davej@codemonkey.org.uk, paulmck@linux.vnet.ibm.com, akpm@linux-foundation.org, mingo@kernel.org, walken@google.com, linux-kernel@vger.kernel.org, jason.low2@hp.com, tglx@linutronix.de, sasha.levin@oracle.com, oleg@redhat.com, hpa@zytor.com, dave@stgolabs.net, tim.c.chen@linux.intel.com, torvalds@linux-foundation.org, peterz@infradead.org In-Reply-To: <1425714331.2475.388.camel@j-VirtualBox> References: <1425714331.2475.388.camel@j-VirtualBox> To: linux-tip-commits@vger.kernel.org Subject: [tip:locking/core] locking/rwsem: Fix lock optimistic spinning when owner is not running Git-Commit-ID: 9198f6edfd9ced74fd90b238d5a354aeac89bdfa X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 9198f6edfd9ced74fd90b238d5a354aeac89bdfa Gitweb: http://git.kernel.org/tip/9198f6edfd9ced74fd90b238d5a354aeac89bdfa Author: Jason Low AuthorDate: Fri, 6 Mar 2015 23:45:31 -0800 Committer: Ingo Molnar CommitDate: Sat, 7 Mar 2015 09:50:49 +0100 locking/rwsem: Fix lock optimistic spinning when owner is not running Ming reported soft lockups occurring when running xfstest due to the following tip:locking/core commit: b3fd4f03ca0b ("locking/rwsem: Avoid deceiving lock spinners") 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, this commit 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 Signed-off-by: Jason Low Acked-by: Davidlohr Bueso Cc: Andrew Morton Cc: Dave Jones Cc: Linus Torvalds Cc: Michel Lespinasse Cc: Oleg Nesterov Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Sasha Levin Cc: Thomas Gleixner Cc: Tim Chen Link: http://lkml.kernel.org/r/1425714331.2475.388.camel@j-VirtualBox Signed-off-by: Ingo Molnar --- kernel/locking/rwsem-xadd.c | 31 +++++++++++-------------------- 1 file 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; }