Thread (96 messages) 96 messages, 15 authors, 2013-11-08

Re: perf events ring buffer memory barrier on powerpc

From: Peter Zijlstra <peterz@infradead.org>
Date: 2013-10-30 17:44:23
Also in: lkml

On Wed, Oct 30, 2013 at 07:14:29PM +0200, Victor Kaplansky wrote:
We need a complete rmb() here IMO. I think there is a fundamental
difference between load and stores in this aspect. Load are allowed to
be hoisted by compiler or executed speculatively by HW. To prevent
load "*(ubuf->data + tail)" to be hoisted beyond "ubuf->head" load you
would need something like this:
Indeed, we could compute and load ->data + tail the moment we've
completed the tail load but before we've completed the head load and
done the comparison.

So yes, full rmb() it is.
void
ubuf_read(void)
{
        u64 head, tail;

        tail = ubuf->tail;
        head = ACCESS_ONCE(ubuf->head);

        /*
         * Ensure we read the buffer boundaries before the actual buffer
         * data...
         */

        while (tail != head) {
		    smp_read_barrier_depends();         /* for Alpha */
                obj = *(ubuf->data + head - 128);
                /* process obj */
                tail += obj->size;
                tail %= ubuf->size;
        }

        /*
         * Ensure all data reads are complete before we issue the
         * ubuf->tail update; once that update hits, kbuf_write() can
         * observe and overwrite data.
         */
        smp_mb();               /* D, matches with A */

        ubuf->tail = tail;
}

(note that "head" is part of address calculation of obj load now).
Right, explicit dependent loads; I was hoping the conditional in between
might be enough, but as argued above it is not. The above cannot work in
our case though, we must use tail to find the obj since we have variable
size objects.
But, even in this demo example some "smp_read_barrier_depends()" before
"obj = *(ubuf->data + head - 100);" is required for architectures
like Alpha. Though, on more sane architectures "smp_read_barrier_depends()"
will be translated to nothing.
Sure.. I know all about that.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help