From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Linux Trace Kernel <linux-trace-kernel@vger.kernel.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Mark Rutland <mark.rutland@arm.com>
Subject: Re: [PATCH] tracing: Fix blocked reader of snapshot buffer
Date: Fri, 29 Dec 2023 22:47:46 +0900 [thread overview]
Message-ID: <20231229224746.6c55e4482a0dadf9d5a3c527@kernel.org> (raw)
In-Reply-To: <20231228095149.77f5b45d@gandalf.local.home>
On Thu, 28 Dec 2023 09:51:49 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
>
> If an application blocks on the snapshot or snapshot_raw files, expecting
> to be woken up when a snapshot occurs, it will not happen. Or it may
> happen with an unexpected result.
>
> That result is that the application will be reading the main buffer
> instead of the snapshot buffer. That is because when the snapshot occurs,
> the main and snapshot buffers are swapped. But the reader has a descriptor
> still pointing to the buffer that it originally connected to.
>
> This is fine for the main buffer readers, as they may be blocked waiting
> for a watermark to be hit, and when a snapshot occurs, the data that the
> main readers want is now on the snapshot buffer.
>
> But for waiters of the snapshot buffer, they are waiting for an event to
> occur that will trigger the snapshot and they can then consume it quickly
> to save the snapshot before the next snapshot occurs. But to do this, they
> need to read the new snapshot buffer, not the old one that is now
> receiving new data.
>
> Also, it does not make sense to have a watermark "buffer_percent" on the
> snapshot buffer, as the snapshot buffer is static and does not receive new
> data except all at once.
This looks good to me.
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Thank you!
>
> Cc: stable@vger.kernel.org
> Fixes: debdd57f5145f ("tracing: Make a snapshot feature available from userspace")
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> ---
> kernel/trace/ring_buffer.c | 3 ++-
> kernel/trace/trace.c | 20 +++++++++++++++++---
> 2 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index e476d42c84c5..07dae67424a9 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
> @@ -838,7 +838,8 @@ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
> /* make sure the waiters see the new index */
> smp_wmb();
>
> - rb_wake_up_waiters(&rbwork->work);
> + /* This can be called in any context */
> + irq_work_queue(&rbwork->work);
> }
>
> /**
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index cfeaf2cd204e..606787edae8c 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -1902,6 +1902,9 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
> __update_max_tr(tr, tsk, cpu);
>
> arch_spin_unlock(&tr->max_lock);
> +
> + /* Any waiters on the old snapshot buffer need to wake up */
> + ring_buffer_wake_waiters(tr->array_buffer.buffer, RING_BUFFER_ALL_CPUS);
> }
>
> /**
> @@ -1953,12 +1956,23 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
>
> static int wait_on_pipe(struct trace_iterator *iter, int full)
> {
> + int ret;
> +
> /* Iterators are static, they should be filled or empty */
> if (trace_buffer_iter(iter, iter->cpu_file))
> return 0;
>
> - return ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file,
> - full);
> + ret = ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, full);
> +
> +#ifdef CONFIG_TRACER_MAX_TRACE
> + /*
> + * Make sure this is still the snapshot buffer, as if a snapshot were
> + * to happen, this would now be the main buffer.
> + */
> + if (iter->snapshot)
> + iter->array_buffer = &iter->tr->max_buffer;
> +#endif
> + return ret;
> }
>
> #ifdef CONFIG_FTRACE_STARTUP_TEST
> @@ -8560,7 +8574,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
>
> wait_index = READ_ONCE(iter->wait_index);
>
> - ret = wait_on_pipe(iter, iter->tr->buffer_percent);
> + ret = wait_on_pipe(iter, iter->snapshot ? 0 : iter->tr->buffer_percent);
> if (ret)
> goto out;
>
> --
> 2.42.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
prev parent reply other threads:[~2023-12-29 13:47 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-28 14:51 [PATCH] tracing: Fix blocked reader of snapshot buffer Steven Rostedt
2023-12-29 13:47 ` Masami Hiramatsu [this message]
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=20231229224746.6c55e4482a0dadf9d5a3c527@kernel.org \
--to=mhiramat@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--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;
as well as URLs for NNTP newsgroup(s).