From: Peter Zijlstra <peterz@infradead.org>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Dmitry Vyukov <dvyukov@google.com>,
ebiederm@xmission.com, Al Viro <viro@zeniv.linux.org.uk>,
Andrew Morton <akpm@linux-foundation.org>,
Ingo Molnar <mingo@kernel.org>,
Paul McKenney <paulmck@linux.vnet.ibm.com>,
mhocko@suse.cz, LKML <linux-kernel@vger.kernel.org>,
ktsan@googlegroups.com, Kostya Serebryany <kcc@google.com>,
Andrey Konovalov <andreyknvl@google.com>,
Alexander Potapenko <glider@google.com>,
Hans Boehm <hboehm@google.com>
Subject: Re: [PATCH] kernel: fix data race in put_pid
Date: Fri, 18 Sep 2015 15:46:30 +0200 [thread overview]
Message-ID: <20150918134630.GW3816@twins.programming.kicks-ass.net> (raw)
In-Reply-To: <20150918132844.GA10241@redhat.com>
On Fri, Sep 18, 2015 at 03:28:44PM +0200, Oleg Nesterov wrote:
> On 09/18, Peter Zijlstra wrote:
> >
> > On Thu, Sep 17, 2015 at 08:09:19PM +0200, Oleg Nesterov wrote:
> >
> > > I need to recheck, but afaics this is not possible. This optimization
> > > is fine, but probably needs a comment.
> >
> > For sure, this code doesn't make any sense to me.
>
> So yes, after a sleep I am starting to agree that in theory this fast-path
> check is wrong. I'll write another email..
This other mail will include a patch adding comments to pid.c ? That
code didn't want to make sense to me this morning.
> > As an alternative patch, could we not do:
> >
> > void put_pid(struct pid *pid)
> > {
> > struct pid_namespace *ns;
> >
> > if (!pid)
> > return;
> >
> > ns = pid->numbers[pid->level].ns;
> > if ((atomic_read(&pid->count) == 1) ||
> > atomic_dec_and_test(&pid->count)) {
> >
> > + smp_read_barrier_depends(); /* ctrl-dep */
>
> Not sure... Firstly it is not clear what this barrier pairs with. And I
> have to admit that I can not understand if _CTRL() logic applies here.
> The same for atomic_read_ctrl().
The control dependency barrier pairs with the full barrier of
atomic_dec_and_test.
So the two put_pid() instances:
CPU0 CPU1
pid->foo = 1;
atomic_dec_and_test() == false atomic_read_ctrl() == 1
kmem_cache_free(pid)
CPU0 will modify a pid field and decrement, but not reach 0.
CPU1 finds we're the last, but must also be able to observe our foo
store such that we can rest assured it is complete before we free the
storage.
The freeing of pid, on CPU1, is stores, these must not happen before we
satisfy the freeing condition, iow a load-store barrier, which is what
the control dependency provides.
> OK, please forget about put_pid() for the moment. Suppose we have
>
> X = 1;
> synchronize_sched();
> Y = 1;
>
> Or
> X = 1;
> call_rcu_sched( func => { Y = 1; } );
>
>
>
> Now. In theory this this code is wrong:
>
> if (Y) {
> BUG_ON(X == 0);
> }
>
> But this is correct:
>
> if (Y) {
> rcu_read_lock_sched();
> rcu_read_unlock_sched();
> BUG_ON(X == 0);
> }
>
> So perhaps something like this
>
> /*
> * Comment to explain it is eq to read_lock + read_unlock,
> * in a sense that this guarantees a full barrier wrt to
> * the previous synchronize_sched().
> */
> #define rcu_read_barrier_sched() barrier()
>
> make sense?
>
>
> And again, I simply can't understand if this code
>
> if (READ_ONCE_CTRL(Y))
> BUG_ON(X == 0);
>
> to me it does _not_ look correct in theory.
So control dependencies provide a load-store barrier. Your examples
above rely on a load-load barrier; BUG_ON(X == 0) is a load.
kmem_cache_free() OTOH is stores (we must modify the free list).
next prev parent reply other threads:[~2015-09-18 13:52 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-17 13:24 [PATCH] kernel: fix data race in put_pid Dmitry Vyukov
2015-09-17 16:08 ` Oleg Nesterov
2015-09-17 16:41 ` Dmitry Vyukov
2015-09-17 17:44 ` Oleg Nesterov
2015-09-17 17:57 ` Dmitry Vyukov
2015-09-17 17:59 ` Dmitry Vyukov
2015-09-17 18:09 ` Oleg Nesterov
2015-09-17 18:38 ` Dmitry Vyukov
2015-09-18 8:51 ` Peter Zijlstra
2015-09-18 8:57 ` Peter Zijlstra
2015-09-18 9:27 ` Peter Zijlstra
2015-09-18 12:31 ` James Hogan
2015-09-18 12:34 ` Peter Zijlstra
2015-09-18 15:56 ` Paul E. McKenney
2015-09-18 9:06 ` Dmitry Vyukov
2015-09-18 9:28 ` Will Deacon
2015-09-18 9:33 ` Peter Zijlstra
2015-09-18 11:22 ` Peter Zijlstra
2015-09-18 11:30 ` Will Deacon
2015-09-18 11:50 ` Dmitry Vyukov
2015-09-18 11:56 ` Peter Zijlstra
2015-09-18 12:19 ` Peter Zijlstra
2015-09-18 12:44 ` Will Deacon
2015-09-18 13:10 ` Peter Zijlstra
2015-09-18 13:44 ` Oleg Nesterov
2015-09-18 13:49 ` Peter Zijlstra
2015-09-18 13:53 ` Dmitry Vyukov
2015-09-18 14:41 ` Oleg Nesterov
2015-09-22 8:38 ` Dmitry Vyukov
2015-09-23 8:48 ` [tip:locking/core] atomic: Implement atomic_read_ctrl() tip-bot for Peter Zijlstra
2015-09-18 16:15 ` [PATCH] kernel: fix data race in put_pid Eric Dumazet
2015-09-18 16:20 ` Peter Zijlstra
2015-09-18 15:57 ` Paul E. McKenney
2015-09-18 13:28 ` Oleg Nesterov
2015-09-18 13:31 ` Oleg Nesterov
2015-09-18 13:46 ` Peter Zijlstra [this message]
2015-09-18 15:00 ` Oleg Nesterov
2015-09-18 15:30 ` Oleg Nesterov
2015-09-18 16:00 ` Paul E. McKenney
2015-09-17 17:56 ` Paul E. McKenney
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=20150918134630.GW3816@twins.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@google.com \
--cc=dvyukov@google.com \
--cc=ebiederm@xmission.com \
--cc=glider@google.com \
--cc=hboehm@google.com \
--cc=kcc@google.com \
--cc=ktsan@googlegroups.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mhocko@suse.cz \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=viro@zeniv.linux.org.uk \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox