RE: [PATCH V3 04/12] perf mmap: introduce perf_mmap__read_done
From: Liang, Kan
Date: Tue Jan 09 2018 - 10:12:41 EST
> > > > >
> > > > > Also I guess the current code might miss some events since the head
> can
> > > be
> > > > > different between _read_init() and _read_done(), no?
> > > > >
> > > >
> > > > The overwrite mode requires the ring buffer to be paused during
> > > processing.
> > > > The head is unchanged between __read_init() and __read_done().
> > >
> > > Ah, ok then. Maybe we could read the head once, and use it during
> > > processing.
> >
> > Yes, it only needs to read head once for overwrite mode.
> > But for non-overwrite, we have to read the head in every
> > perf_mmap__read_event(). Because the head is floating.
> > The non-overwrite is specially handled in patch 5/12 as well.
>
> Right, I understand it for the non-overwrite mode.
>
> But, for the overwrite mode, my concern was that it might be possible
> that it reads a stale head in __read_init() (even after it paused the
> ring buffer) and reads an update head in __read_done(). Then it's
> gonna miss some records. I'm not sure whether it reads the same head
> in __read_init() and __read_done() by the pause.
>
The only scenario which may cause the different 'head' may be as below.
The 'rb->head' is updated in __perf_output_begin(), but havenât been
assigned to 'pc->data_head' for perf tool. During this period, the 'paused'
is set and __read_init() reads head.
But this scenario never happens because of the ringbuffer lock.
Otherwise, I cannot imagine any other scenarios which may causes the
different 'head' in __read_init() and __read_done() with ringbuffer
paused. Please let me know if there is an example.
There would be some records miss. But it's only because the ringbuffer
is paused. The head should keep the same.
I also did some tests and dump the 'head' in __read_init() and
__read_done() with ringbuffer paused. I didn't see any difference either.
Thanks,
Kan
> Thanks,
> Namhyung
>
>
> > + /* non-overwirte doesn't pause the ringbuffer */
> > + if (!overwrite)
> > + end = perf_mmap__read_head(map);