| From 655a00cb0dbef586b2def7ce6eea039b8cb99163 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 5 Dec 2023 16:52:10 -0500 |
| Subject: tracing: Stop current tracer when resizing buffer |
| |
| From: Steven Rostedt (Google) <rostedt@goodmis.org> |
| |
| [ Upstream commit d78ab792705c7be1b91243b2544d1a79406a2ad7 ] |
| |
| When the ring buffer is being resized, it can cause side effects to the |
| running tracer. For instance, there's a race with irqsoff tracer that |
| swaps individual per cpu buffers between the main buffer and the snapshot |
| buffer. The resize operation modifies the main buffer and then the |
| snapshot buffer. If a swap happens in between those two operations it will |
| break the tracer. |
| |
| Simply stop the running tracer before resizing the buffers and enable it |
| again when finished. |
| |
| Link: https://lkml.kernel.org/r/20231205220010.748996423@goodmis.org |
| |
| Cc: stable@vger.kernel.org |
| Cc: Masami Hiramatsu <mhiramat@kernel.org> |
| Cc: Mark Rutland <mark.rutland@arm.com> |
| Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| Cc: Andrew Morton <akpm@linux-foundation.org> |
| Fixes: 3928a8a2d9808 ("ftrace: make work with new ring buffer") |
| Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| kernel/trace/trace.c | 10 +++++++--- |
| 1 file changed, 7 insertions(+), 3 deletions(-) |
| |
| diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c |
| index 049daa6a9ad42..657ecb8f03545 100644 |
| --- a/kernel/trace/trace.c |
| +++ b/kernel/trace/trace.c |
| @@ -6243,9 +6243,12 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, |
| if (!tr->array_buffer.buffer) |
| return 0; |
| |
| + /* Do not allow tracing while resizng ring buffer */ |
| + tracing_stop_tr(tr); |
| + |
| ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu); |
| if (ret < 0) |
| - return ret; |
| + goto out_start; |
| |
| #ifdef CONFIG_TRACER_MAX_TRACE |
| if (!tr->current_trace->use_max_tr) |
| @@ -6273,7 +6276,7 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, |
| WARN_ON(1); |
| tracing_disabled = 1; |
| } |
| - return ret; |
| + goto out_start; |
| } |
| |
| update_buffer_entries(&tr->max_buffer, cpu); |
| @@ -6282,7 +6285,8 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, |
| #endif /* CONFIG_TRACER_MAX_TRACE */ |
| |
| update_buffer_entries(&tr->array_buffer, cpu); |
| - |
| + out_start: |
| + tracing_start_tr(tr); |
| return ret; |
| } |
| |
| -- |
| 2.42.0 |
| |