On Tue, 2013-05-28 at 18:31 -0700, Paul E. McKenney wrote: > On Tue, May 28, 2013 at 05:34:53PM -0700, Eric Dumazet wrote: > > On Tue, 2013-05-28 at 13:10 +0400, Roman Gushchin wrote: > > > On 28.05.2013 04:12, Eric Dumazet wrote: > > > > > > Adding a barrier() is probably what we want. > > > > > > I agree, inserting barrier() is also a correct and working fix. > > > > Yeah, but I can not find a clean way to put it inside the "for (;;)" > > > > for (barrier();;) -> > > > > error: expected expression before ‘__asm__’ > > > > No user currently does : > > > > if (condition) > > hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) > > > > But who knows... > > I still have my earlier question, but I suggest "({ barrier(); XXX })" > to put the barrier into the for loop, either in the second or third > clause, where XXX was the original second or third clause. > >
Hmm, it doesn't work, I wanted to replace : barrier(); for (expr1 ; expr2; expr3) { by : for ( some_clever_thing ; expr2; expr3) { So barrier() should not be in second or third clause : it must be done once and before "expr1". Not a big deal anyway, we're not adding new hlist_nulls_for_each_entry_rcu() users :) About your earlier question, I really don't know why compiler would cache a memory read if we explicitly use barrier() to prevent this from happening. BTW Roman patch generates a double load as in : 2cb1: 49 8b 07 mov (%r15),%rax 2cb4: 49 8b 07 mov (%r15),%rax ... 2ea2: e8 f9 dc ff ff callq ba0 <sock_put> 2ea7: 8b 0c 24 mov (%rsp),%ecx 2eaa: e9 02 fe ff ff jmpq 2cb1 <udp4_lib_lookup2+0x91> because of ACCESS_ONCE() used twice, once explicitly in hlist_nulls_for_each_entry_rcu(), and once in rcu_dereference_raw() While barrier();ptr = rcu_dereference(X); does generate a single load. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/