From: Peter Zijlstra <peterz@infradead.org>
To: Oleg Nesterov <oleg@redhat.com>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
linux-kernel@vger.kernel.org, dave@stgolabs.net,
waiman.long@hp.com, raghavendra.kt@linux.vnet.ibm.com,
Nicholas Mc Guire <der.herr@hofr.at>,
Linus Torvalds <torvalds@linux-foundation.org>,
mingo@kernel.org
Subject: Re: [PATCH] sched/completion: completion_done() should serialize with complete()
Date: Mon, 16 Feb 2015 09:21:13 +0100 [thread overview]
Message-ID: <20150216082113.GY5029@twins.programming.kicks-ass.net> (raw)
In-Reply-To: <20150212195913.GA30430@redhat.com>
On Thu, Feb 12, 2015 at 08:59:13PM +0100, Oleg Nesterov wrote:
> 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().
So I share Davidlohrs concern if we should not simply revert that
change; but given we've now gone over it detail I suppose we should just
keep the optimized version.
I did add a comment to your patch; and queued the below for
sched/urgent.
---
Subject: sched/completion: completion_done() should serialize with complete()
From: Oleg Nesterov <oleg@redhat.com>
Date: Thu, 12 Feb 2015 20:59:13 +0100
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().
Fixes: de30ec47302c ("sched/completion: Remove unnecessary ->wait.lock serialization when reading completion state")
Cc: waiman.long@hp.com
Cc: raghavendra.kt@linux.vnet.ibm.com
Cc: dave@stgolabs.net
Cc: Nicholas Mc Guire <der.herr@hofr.at>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Reported-by: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Tested-by: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Reported-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
[peterz: Add a comment with the barrier]
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150212195913.GA30430@redhat.com
---
kernel/sched/completion.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
--- a/kernel/sched/completion.c
+++ b/kernel/sched/completion.c
@@ -274,7 +274,7 @@ bool try_wait_for_completion(struct comp
* 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);
next prev parent reply other threads:[~2015-02-16 8:21 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-12 0:34 BUG: spinlock bad magic on CPU#0, migration/0/9 Paul E. McKenney
2015-02-12 3:15 ` Davidlohr Bueso
2015-02-12 3:43 ` Paul E. McKenney
2015-02-12 17:28 ` Oleg Nesterov
2015-02-12 17:41 ` Oleg Nesterov
2015-02-12 17:58 ` Davidlohr Bueso
2015-02-12 19:10 ` Nicholas Mc Guire
2015-02-12 19:37 ` Oleg Nesterov
2015-02-12 21:27 ` Oleg Nesterov
2015-02-13 18:17 ` Nicholas Mc Guire
2015-02-13 18:53 ` Oleg Nesterov
2015-02-14 8:35 ` Nicholas Mc Guire
2015-02-14 14:00 ` Oleg Nesterov
2015-02-12 19:59 ` Davidlohr Bueso
2015-02-12 19:32 ` Nicholas Mc Guire
2015-02-12 19:39 ` Oleg Nesterov
2015-02-12 19:59 ` [PATCH] sched/completion: completion_done() should serialize with complete() Oleg Nesterov
2015-02-13 21:09 ` Paul E. McKenney
2015-02-13 21:56 ` Davidlohr Bueso
2015-02-13 22:02 ` Davidlohr Bueso
2015-02-16 8:21 ` Peter Zijlstra [this message]
2015-02-16 16:51 ` Oleg Nesterov
2015-02-18 17:06 ` [tip:sched/core] sched/completion: Serialize completion_done() " tip-bot for Oleg Nesterov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150216082113.GY5029@twins.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=dave@stgolabs.net \
--cc=der.herr@hofr.at \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=raghavendra.kt@linux.vnet.ibm.com \
--cc=torvalds@linux-foundation.org \
--cc=waiman.long@hp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.