Re: [PATCH v2] ring-buffer: Handle a reader taking the new head in rb_handle_head_page()

From: Steven Rostedt

Date: Mon Nov 09 2026 - 02:23:33 EST


On Thu, 5 Nov 2026 15:57:29 -0500
Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:

> We may need to add memory barriers here, but for now, I think this could
> fix it. As it should prevent the search from ever starting in between the
> two heads.

Yeah, I think this will do it. Please test, I'll go write up a formal patch:

-- Steve

diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index c64e001c3fc0..0d37f8b529d5 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1494,7 +1494,13 @@ rb_set_head_page(struct ring_buffer_per_cpu *cpu_buffer)
if (RB_WARN_ON(cpu_buffer, rb_list_head(list->prev->next) != list))
return NULL;

- page = head = cpu_buffer->head_page;
+ /*
+ * Make sure that the start of the search of the head_page does not
+ * start between the writer adding the UPDATE and the new HEAD that it
+ * moves forward.
+ */
+ /* Sync with the writer moving the HEAD in rb_handle_head_page() */
+ page = head = smp_load_acquire(&cpu_buffer->head_page);
/*
* It is possible that the writer moves the header behind
* where we started, and we miss in one loop.
@@ -3721,6 +3727,15 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
local_sub(rb_page_commit(next_page), &cpu_buffer->entries_bytes);
local_inc(&cpu_buffer->pages_lost);

+ /*
+ * To prevent a stale head_page from being between
+ * the UPDATE and new HEAD pages, set it here to have
+ * the reader check always find the update before
+ * finding the HEAD page.
+ */
+ /* Sync with the reader setting the head page */
+ smp_store_release(&cpu_buffer->head_page, next_page);
+
if (cpu_buffer->ring_meta)
rb_update_meta_head(cpu_buffer, next_page);
/*
--
2.53.0