Re: [PATCH] kernel: fix data race in put_pid

From: Dmitry Vyukov
Date: Fri Sep 18 2015 - 09:53:34 EST


On Fri, Sep 18, 2015 at 3:44 PM, Oleg Nesterov <oleg@xxxxxxxxxx> wrote:
> On 09/18, Peter Zijlstra wrote:
>>
>> Provide atomic_read_ctrl() to mirror READ_ONCE_CTRL(), such that we can
>> more conveniently use atomics in control dependencies.
>>
>> Since we can assume atomic_read() implies a READ_ONCE(), we must only
>> emit an extra smp_read_barrier_depends() in order to upgrade to
>> READ_ONCE_CTRL() semantics.
>
> ...
>
>> +static inline int atomic_read_ctrl(atomic_t *v)
>> +{
>> + int val = atomic_read(v);
>> + smp_read_barrier_depends(); /* Enforce control dependency. */
>> + return val;
>> +}
>
> Help. I am starting to think that the control dependencies is even more
> hard to understand that memory barriers...
>
> So I assume that if we have
>
> int X = 0;
> atomic_t Y = ATOMIC_INIT(0);
>
> void w(void)
> {
> X = 1;
> atomic_inc_return(&Y);
> }
>
> then
>
> void r(void)
> {
> if (atomic_read_ctrl(&Y))
> BUG_ON(X == 0);
> }
>
> should be correct? Why?
>
> If not then I am even more confused.

This not correct, because "ctrl" barrier affects only
control-dependent stores. For reads processor still can speculate,
that is, speculatively load X before loading Y. Control-dependent
require full read/acquire memory barrier.
What will work is:

// thread 1
X = 1;
atomic_inc_return(&Y);

// thread 2
if (atomic_read_ctrl(&Y)) {
X = 2;
BUG_ON(X == 2);
}

Without the "ctrl" barrier store X=2 could hoist above load of Y (on
Alpha), and then X=1 can happen _after_ X=2, and then BUG_ON could
fail.
With the "ctrl" barrier store X=2 is not allowed to hoist above load of Y.


--
Dmitry Vyukov, Software Engineer, dvyukov@xxxxxxxxxx
Google Germany GmbH, DienerstraÃe 12, 80331, MÃnchen
GeschÃftsfÃhrer: Graham Law, Christine Elizabeth Flores
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Diese E-Mail ist vertraulich. Wenn Sie nicht der richtige Adressat
sind, leiten Sie diese bitte nicht weiter, informieren Sie den
Absender und lÃschen Sie die E-Mail und alle AnhÃnge. Vielen Dank.
This e-mail is confidential. If you are not the right addressee please
do not forward it, please inform the sender, and please erase this
e-mail including any attachments. Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/