Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753358AbbBRRIi (ORCPT ); Wed, 18 Feb 2015 12:08:38 -0500 Received: from terminus.zytor.com ([198.137.202.10]:39008 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752546AbbBRRIg (ORCPT ); Wed, 18 Feb 2015 12:08:36 -0500 Date: Wed, 18 Feb 2015 09:06:55 -0800 From: tip-bot for Oleg Nesterov Message-ID: Cc: torvalds@linux-foundation.org, mingo@kernel.org, peterz@infradead.org, tglx@linutronix.de, oleg@redhat.com, dave@stgolabs.net, linux-kernel@vger.kernel.org, hpa@zytor.com, der.herr@hofr.at, paulmck@linux.vnet.ibm.com Reply-To: hpa@zytor.com, linux-kernel@vger.kernel.org, dave@stgolabs.net, oleg@redhat.com, tglx@linutronix.de, paulmck@linux.vnet.ibm.com, der.herr@hofr.at, peterz@infradead.org, mingo@kernel.org, torvalds@linux-foundation.org In-Reply-To: <20150212195913.GA30430@redhat.com> References: <20150212195913.GA30430@redhat.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:sched/core] sched/completion: Serialize completion_done() with complete() Git-Commit-ID: bc9560155f4063bbc9be71bd69d6726d41b47653 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 Content-Length: 2977 Lines: 79 Commit-ID: bc9560155f4063bbc9be71bd69d6726d41b47653 Gitweb: http://git.kernel.org/tip/bc9560155f4063bbc9be71bd69d6726d41b47653 Author: Oleg Nesterov AuthorDate: Thu, 12 Feb 2015 20:59:13 +0100 Committer: Ingo Molnar CommitDate: Wed, 18 Feb 2015 14:27:40 +0100 sched/completion: Serialize completion_done() with complete() Commit de30ec47302c "Remove unnecessary ->wait.lock serialization when reading completion state" was not correct, without lock/unlock the code like stop_machine_from_inactive_cpu() while (!completion_done()) cpu_relax(); can return before complete() finishes its spin_unlock() which writes to this memory. And spin_unlock_wait(). While at it, change try_wait_for_completion() to use READ_ONCE(). Reported-by: Paul E. McKenney Reported-by: Davidlohr Bueso Tested-by: Paul E. McKenney Signed-off-by: Oleg Nesterov Signed-off-by: Peter Zijlstra (Intel) [ Added a comment with the barrier. ] Cc: Linus Torvalds Cc: Nicholas Mc Guire Cc: raghavendra.kt@linux.vnet.ibm.com Cc: waiman.long@hp.com Fixes: de30ec47302c ("sched/completion: Remove unnecessary ->wait.lock serialization when reading completion state") Link: http://lkml.kernel.org/r/20150212195913.GA30430@redhat.com Signed-off-by: Ingo Molnar --- kernel/sched/completion.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/kernel/sched/completion.c b/kernel/sched/completion.c index 7052d3f..8d0f35d 100644 --- a/kernel/sched/completion.c +++ b/kernel/sched/completion.c @@ -274,7 +274,7 @@ bool try_wait_for_completion(struct completion *x) * first without taking the lock so we can * return early in the blocking case. */ - if (!ACCESS_ONCE(x->done)) + if (!READ_ONCE(x->done)) return 0; spin_lock_irqsave(&x->wait.lock, flags); @@ -297,6 +297,21 @@ EXPORT_SYMBOL(try_wait_for_completion); */ bool completion_done(struct completion *x) { - return !!ACCESS_ONCE(x->done); + if (!READ_ONCE(x->done)) + return false; + + /* + * If ->done, we need to wait for complete() to release ->wait.lock + * otherwise we can end up freeing the completion before complete() + * is done referencing it. + * + * The RMB pairs with complete()'s RELEASE of ->wait.lock and orders + * the loads of ->done and ->wait.lock such that we cannot observe + * the lock before complete() acquires it while observing the ->done + * after it's acquired the lock. + */ + smp_rmb(); + spin_unlock_wait(&x->wait.lock); + return true; } EXPORT_SYMBOL(completion_done); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/