ring-buffer: Don't deactivate the ring buffer on failed iterator reads

If the function tracer is running and the trace file is read (which uses the
ring buffer iterator), the iterator can get in sync with the writes, and
caues it to fail to find a page with content it can read three times. This
causes a warning and deactivation of the ring buffer code.

Looking at the other cases of failure to get an event, it appears that
there's a chance that the writer could cause them too. Since the iterator is
a "best effort" to read the ring buffer if there's an active writer (the
consumer reader is made for this case "see trace_pipe"), if it fails to get
an event after three tries, simply give up and return NULL. Don't warn, nor
disable the ring buffer on this failure.

Link: https://lore.kernel.org/r/20200429090508.GG5770@shao2-debianReported-by: default avatarkernel test robot <lkp@intel.com>
Fixes: ff84c50c ("ring-buffer: Do not die if rb_iter_peek() fails more than thrice")
Tested-by: default avatarSven Schnelle <svens@linux.ibm.com>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 59566b0b
...@@ -4034,7 +4034,6 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) ...@@ -4034,7 +4034,6 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
struct ring_buffer_per_cpu *cpu_buffer; struct ring_buffer_per_cpu *cpu_buffer;
struct ring_buffer_event *event; struct ring_buffer_event *event;
int nr_loops = 0; int nr_loops = 0;
bool failed = false;
if (ts) if (ts)
*ts = 0; *ts = 0;
...@@ -4056,19 +4055,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) ...@@ -4056,19 +4055,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
return NULL; return NULL;
/* /*
* We repeat when a time extend is encountered or we hit * As the writer can mess with what the iterator is trying
* the end of the page. Since the time extend is always attached * to read, just give up if we fail to get an event after
* to a data event, we should never loop more than three times. * three tries. The iterator is not as reliable when reading
* Once for going to next page, once on time extend, and * the ring buffer with an active write as the consumer is.
* finally once to get the event. * Do not warn if the three failures is reached.
* We should never hit the following condition more than thrice, */
* unless the buffer is very small, and there's a writer if (++nr_loops > 3)
* that is causing the reader to fail getting an event.
*/
if (++nr_loops > 3) {
RB_WARN_ON(cpu_buffer, !failed);
return NULL; return NULL;
}
if (rb_per_cpu_empty(cpu_buffer)) if (rb_per_cpu_empty(cpu_buffer))
return NULL; return NULL;
...@@ -4079,10 +4073,8 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) ...@@ -4079,10 +4073,8 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
} }
event = rb_iter_head_event(iter); event = rb_iter_head_event(iter);
if (!event) { if (!event)
failed = true;
goto again; goto again;
}
switch (event->type_len) { switch (event->type_len) {
case RINGBUF_TYPE_PADDING: case RINGBUF_TYPE_PADDING:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment