Messages in this thread | | | Subject | Re: [PATCH] ring-buffer: fix uninitialized read_stamp | From | Steven Rostedt <> | Date | Thu, 21 Jun 2012 11:46:57 -0400 |
| |
OK, I did look at this more.
On Mon, 2012-06-18 at 16:02 -0700, David Sharp wrote: > This fixes a scenario in which trace_pipe_raw will return events with invalid > timestamps when events are copied out one at a time (instead of swapping out > the reader page with a spare page). In this scenario, ring_buffer_read_page() > uses cpu_buffer->read_stamp to keep track of the time of the earliest event. > However, cpu_buffer->read_stamp was not always updated.
> The only function that > sets read_stamp to a new valid value is rb_reset_reader_page(), which is called > only by rb_get_reader_page().
Correct, which is the only way to get the reader page no matter how you read the buffer.
> rb_reset_reader_page() was not called when there > is data immediately available on the page to read (read < rb_page_size()). This > is the bug.
It is not called? but how did you get the reader_page without the swap in the first place?
When the ring buffer is first allocated the reader page is set to a zero'd page, making the "read" and "commit" both zero.
The first time rb_get_reader_page() is called, the compare of read < rb_page_size() (which is the commit field) fails (0 < 0 is false).
A swap from the writable ring buffer takes place and the cpu_buffer->read_stamp is updated.
Ah! I think this is where the bug you see happens. But your analysis is flawed.
If the ring buffer is currently empty, we swap an empty page for an empty page. But the writer ends up on the reader page preventing new swaps from taking place.
commit_page == reader_page
If the writer starts writing, it will update the time stamp of the page. If your next read happens now, and it's just a single read, then you are correct that it will not update the read_stamp.
I'm wondering if it would be better to just not do the swap, and return NULL when it is empty. This would also fix the problem, as the read_stamp will only be set when you actually have data.
Or it may just be simpler to take your patch.
-- Steve
| |