|
@@ -464,6 +464,8 @@ struct ring_buffer_iter {
|
|
|
struct ring_buffer_per_cpu *cpu_buffer;
|
|
|
unsigned long head;
|
|
|
struct buffer_page *head_page;
|
|
|
+ struct buffer_page *cache_reader_page;
|
|
|
+ unsigned long cache_read;
|
|
|
u64 read_stamp;
|
|
|
};
|
|
|
|
|
@@ -2716,6 +2718,8 @@ static void rb_iter_reset(struct ring_buffer_iter *iter)
|
|
|
iter->read_stamp = cpu_buffer->read_stamp;
|
|
|
else
|
|
|
iter->read_stamp = iter->head_page->page->time_stamp;
|
|
|
+ iter->cache_reader_page = cpu_buffer->reader_page;
|
|
|
+ iter->cache_read = cpu_buffer->read;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -3066,6 +3070,15 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
|
|
|
cpu_buffer = iter->cpu_buffer;
|
|
|
buffer = cpu_buffer->buffer;
|
|
|
|
|
|
+ /*
|
|
|
+ * Check if someone performed a consuming read to
|
|
|
+ * the buffer. A consuming read invalidates the iterator
|
|
|
+ * and we need to reset the iterator in this case.
|
|
|
+ */
|
|
|
+ if (unlikely(iter->cache_read != cpu_buffer->read ||
|
|
|
+ iter->cache_reader_page != cpu_buffer->reader_page))
|
|
|
+ rb_iter_reset(iter);
|
|
|
+
|
|
|
again:
|
|
|
/*
|
|
|
* We repeat when a timestamp is encountered.
|