Messages in this thread | | | Date | Fri, 18 Jan 2019 10:53:48 -0800 | From | "Paul E. McKenney" <> | Subject | Re: Plain accesses and data races in the Linux Kernel Memory Model |
| |
On Thu, Jan 17, 2019 at 02:43:54PM -0500, Alan Stern wrote: > On Wed, 16 Jan 2019, Andrea Parri wrote: > > > Can the compiler (maybe, it does?) transform, at the C or at the "asm" > > level, LB1's P0 in LB2's P0 (LB1 and LB2 are reported below)? > > > > C LB1 > > > > { > > int *x = &a; > > } > > > > P0(int **x, int *y) > > { > > int *r0; > > > > r0 = rcu_dereference(*x); > > *r0 = 0; > > smp_wmb(); > > WRITE_ONCE(*y, 1); > > } > > > > P1(int **x, int *y, int *b) > > { > > int r0; > > > > r0 = READ_ONCE(*y); > > rcu_assign_pointer(*x, b); > > } > > > > exists (0:r0=b /\ 1:r0=1) > > > > > > C LB2 > > > > { > > int *x = &a; > > } > > > > P0(int **x, int *y) > > { > > int *r0; > > > > r0 = rcu_dereference(*x); > > if (*r0) > > *r0 = 0; > > smp_wmb(); > > WRITE_ONCE(*y, 1); > > } > > > > P1(int **x, int *y, int *b) > > { > > int r0; > > > > r0 = READ_ONCE(*y); > > rcu_assign_pointer(*x, b); > > } > > > > exists (0:r0=b /\ 1:r0=1) > > > > LB1 and LB2 are data-race free, according to the patch; LB1's "exists" > > clause is not satisfiable, while LB2's "exists" clause is satisfiable. > > Umm. Transforming > > *r0 = 0; > > to > > if (*r0 != 0) > *r0 = 0; > > wouldn't work on Alpha if r0 was assigned from a plain read with no > memory barrier between. But when r0 is assigned from an > rcu_dereference call, or if there's no indirection (as in "if (a != 0) > a = 0;"), the compiler is indeed allowed to perform this > transformation. > > This means my definition of preserved writes was wrong; a write we > thought had to be preserved could instead be transformed into a read. > > This objection throws a serious monkey wrench into my approach. For > one thing, it implies that (as in the example) we can't expect > smp_wmb() always to order plain writes. For another, it means we have > to assume a lot more writes need not be preserved. > > I don't know. This may doom the effort to formalize dependencies to > plain accesses. Or at least, those other than address dependencies > from marked reads.
(Catching up, hello from Auckland!)
At this point, I am very much in favor of taking the simpler starting point. If someone is using any sort of dependency from a plain access, all bets are off. Similarly, if someone is using a control or data dependency even from a marked access, the later dependent access must be marked to guarantee ordering.
I believe that the transformation from "*r0 = 0" should be convincing. ;-)
Thanx, Paul
| |