From: Steven Rostedt <[email protected]>

On bootup if the persistent ring buffer finds an invalid sub-buffer, it
only invalidates the invalid sub-buffer and continues. Several sub-buffers
may be invalid and this can cause the iterator to loop more than 3 times
looking for a new event. If that happens, then it returns NULL. Having a
NULL return early can confuse the iterator looking for the next event, and
may show events out of order.

Have the same logic for the consuming read for the iterator that will
allow the loop to find the next event to happen the number of sub-buffers
and not just 3.

Fixes: **TBD** ring-buffer: Skip invalid sub-buffers when validating persistent 
ring buffer
Signed-off-by: Steven Rostedt <[email protected]>
---
 kernel/trace/ring_buffer.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index c6c2f92bfc24..bda53a2d2159 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -6103,12 +6103,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_event *event;
        int nr_loops = 0;
+       int max_loops;
 
        if (ts)
                *ts = 0;
 
        cpu_buffer = iter->cpu_buffer;
        buffer = cpu_buffer->buffer;
+       max_loops = cpu_buffer->ring_meta ? cpu_buffer->nr_pages : 3;
 
        /*
         * Check if someone performed a consuming read to the buffer
@@ -6131,7 +6133,7 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
         * the ring buffer with an active write as the consumer is.
         * Do not warn if the three failures is reached.
         */
-       if (++nr_loops > 3)
+       if (++nr_loops > max_loops)
                return NULL;
 
        if (rb_per_cpu_empty(cpu_buffer))
-- 
2.53.0



Reply via email to