From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org
Subject: Re: [PATCH v3 1/2] tracing: ring_buffer: Rewind persistent ring buffer when reboot
Date: Mon, 26 May 2025 12:44:03 +0900 [thread overview]
Message-ID: <20250526124403.3bf41a0634733b640620ad8a@kernel.org> (raw)
In-Reply-To: <20250523192053.47054e6e@gandalf.local.home>
On Fri, 23 May 2025 19:20:53 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Fri, 23 May 2025 16:54:25 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
>
> > > spin:
> > > @@ -6642,7 +6739,6 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
> > > cpu_buffer->read_bytes += rb_page_size(reader);
> > >
> > > /* swap the pages */
> > > - rb_init_page(bpage);
> >
> > This isn't needed, because the persistent ring buffer is never swapped. And
> > this is what caused my test to fail. For some reason (and I'm still trying
> > to figure out exactly why), it causes my stress test that runs:
> >
> > perf record -o perf-test.dat -a -- trace-cmd record -e all -p function /work/c/hackbench 10 || exit -1
> >
> > To never end after tracing is stopped, and it fills up all the disk space.
Thanks for sharing the test code. So it means perf reads the ring buffer
endlessly?
[reader commit=X1, ts=1]
[head commit=X2, ts=2]...[tail commit=Xn, ts=n]
| |
|---------------------------|
I thought that the read will end when it hits tail or ts < ts_current.
> >
> > But again, this part isn't needed because the persistent ring buffer
> > doesn't do the swapping. This replaces what the user passed in with the
> > current page.
> >
> > > bpage = reader->page;
> > > reader->page = data_page->data;
> > > local_set(&reader->write, 0);
>
> So I analyzed why this fails and we need to reset the commit here.
>
> Adding a bunch of trace_printk() (and using the new trace_printk_dest
> option where I can have trace_printk go into an instance) I was able to see
> why this was an issue.
>
> This part of the code swaps the reader page with what was passed in by the
> caller. The page doesn't go back into the write part of the ring buffer.
> The "commit" field is used to know if there's more data or not.
>
> By not resetting the "commit" field, we have:
>
> reader = rb_get_reader_page(cpu_buffer)
> if (cpu_buffer->reader_page->read < rb_page_size(reader))
> return reader;
> // swap passed in page with reader
>
> Without resetting "commit", the caller consumes the page and then uses that
> same page to pass back to this function. Since the "commit" field is never
> zero'd, it the above if statement always returns true! And this function
> just keeps swapping the reader each time and goes into an infinite loop
> (this loop requires user space to do a read or splice on this page so it's
> not a kernel infinite loop).
Ah, in rb_get_reader_page(cpu_buffer),
/* If there's more to read, return this page */
if (cpu_buffer->reader_page->read < rb_page_size(reader))
goto out;
/* Never should we have an index greater than the size */
if (RB_WARN_ON(cpu_buffer,
cpu_buffer->reader_page->read > rb_page_size(reader)))
goto out;
/* check if we caught up to the tail */
reader = NULL;
if (cpu_buffer->commit_page == cpu_buffer->reader_page)
goto out;
It checks remaining (unread) data first, and move to the next.
>
> Now the question is, can this affect the persistent ring buffer too? I'll
> memory map the buffer and see if it causes the same issue.
Yeah, it can happen, but I didn't hit that.
Let me test it too.
Hmm, BTW, is there any possible solution? records the consumed
bytes in meta data?
>
> -- Steve
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
next prev parent reply other threads:[~2025-05-26 3:44 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-22 15:54 [PATCH v3 0/2] tracing: Rewind persistent ring buffer Masami Hiramatsu (Google)
2025-05-22 15:54 ` [PATCH v3 1/2] tracing: ring_buffer: Rewind persistent ring buffer when reboot Masami Hiramatsu (Google)
2025-05-23 20:54 ` Steven Rostedt
2025-05-23 21:28 ` Steven Rostedt
2025-05-26 3:03 ` Masami Hiramatsu
2025-05-27 0:17 ` Masami Hiramatsu
2025-05-27 3:15 ` Masami Hiramatsu
2025-05-27 3:54 ` Masami Hiramatsu
2025-05-27 13:47 ` Steven Rostedt
2025-05-28 0:22 ` Masami Hiramatsu
2025-05-23 23:20 ` Steven Rostedt
2025-05-26 3:44 ` Masami Hiramatsu [this message]
2025-05-27 13:48 ` Steven Rostedt
2025-06-03 16:00 ` Steven Rostedt
2025-06-03 21:58 ` Masami Hiramatsu
2025-05-22 15:54 ` [PATCH v3 2/2] tracing: Reset last-boot buffers when reading out all cpu buffers Masami Hiramatsu (Google)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250526124403.3bf41a0634733b640620ad8a@kernel.org \
--to=mhiramat@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®