"Paul E. McKenney" <paul...@linux.vnet.ibm.com> wrote on 10/30/2013 11:27:25 AM:
> If you were to back up that insistence with a description of the orderings > you are relying on, why other orderings are not important, and how the > important orderings are enforced, I might be tempted to pay attention > to your opinion. > > Thanx, Paul NP, though, I feel too embarrassed to explain things about memory barriers when one of the authors of Documentation/memory-barriers.txt is on cc: list ;-) Disclaimer: it is anyway impossible to prove lack of *any* problem. Having said that, lets look into an example in Documentation/circular-buffers.txt: > THE PRODUCER > ------------ > > The producer will look something like this: > > spin_lock(&producer_lock); > > unsigned long head = buffer->head; > unsigned long tail = ACCESS_ONCE(buffer->tail); > > if (CIRC_SPACE(head, tail, buffer->size) >= 1) { > /* insert one item into the buffer */ > struct item *item = buffer[head]; > > produce_item(item); > > smp_wmb(); /* commit the item before incrementing the head */ > > buffer->head = (head + 1) & (buffer->size - 1); > > /* wake_up() will make sure that the head is committed before > * waking anyone up */ > wake_up(consumer); > } > > spin_unlock(&producer_lock); We can see that authors of the document didn't put any memory barrier after "buffer->tail" read and before "produce_item(item)" and I think they have a good reason. Lets consider an imaginary smp_mb() right before "produce_item(item);". Such a barrier will ensure that - - the memory read on "buffer->tail" is completed before store to memory pointed by "item" is committed. However, the store to "buffer->tail" anyway cannot be completed before conditional branch implied by "if ()" is proven to execute body statement of the if(). And the latter cannot be proven before read of "buffer->tail" is completed. Lets see this other way. Lets imagine that somehow a store to the data pointed by "item" is completed before we read "buffer->tail". That would mean, that the store was completed speculatively. But speculative execution of conditional stores is prohibited by C/C++ standard, otherwise any conditional store at any random place of code could pollute shared memory. On the other hand, if compiler or processor can prove that condition in above if() is going to be true (or if speculative store writes the same value as it was before write), the speculative store *is* allowed. In this case we should not be bothered by the fact that memory pointed by "item" is written before a read from "buffer->tail" is completed. Regards, -- Victor _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev