[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230409024616.31099-1-Tze-nan.Wu@mediatek.com>
Date: Sun, 9 Apr 2023 10:46:15 +0800
From: Tze-nan Wu <Tze-nan.Wu@...iatek.com>
To: <rostedt@...dmis.org>, <mhiramat@...nel.org>
CC: <bobule.chang@...iatek.com>, <wsd_upstream@...iatek.com>,
<Tze-nan.Wu@...iatek.com>, <stable@...r.kernel.org>,
"AngeloGioacchino Del Regno"
<angelogioacchino.delregno@...labora.com>,
<linux-kernel@...r.kernel.org>,
<linux-trace-kernel@...r.kernel.org>,
<linux-arm-kernel@...ts.infradead.org>,
<linux-mediatek@...ts.infradead.org>
Subject: [PATCH v2] ring-buffer: Prevent inconsistent operation on cpu_buffer->resize_disabled
Write to buffer_size_kb can permanently fail due to cpu_online_mask changed
between two for_each_online_buffer_cpu loops.
The number of increasing and decreasing on cpu_buffer->resize_disable
may be inconsistent, leading that the resize_disabled in some CPUs
becoming none zero after ring_buffer_reset_online_cpus return.
This issue can be reproduced by "echo 0 > trace" and hotplug cpu at the
same time. After reproducing success, we can find out buffer_size_kb
will not be functional anymore.
This patch uses cpus_read_lock() to prevent cpu_online_mask being changed
between two different "for_each_online_buffer_cpu".
Changes in v2:
Use cpus_read_lock() instead of copying cpu_online_mask at the entry of
function
Link:
https://lore.kernel.org/lkml/20230408052226.25268-1-Tze-nan.Wu@mediatek.com/
Cc: stable@...r.kernel.org
Signed-off-by: Tze-nan Wu <Tze-nan.Wu@...iatek.com>
---
kernel/trace/ring_buffer.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 76a2d91eecad..44d833252fb0 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -5357,6 +5357,7 @@ void ring_buffer_reset_online_cpus(struct trace_buffer *buffer)
/* prevent another thread from changing buffer sizes */
mutex_lock(&buffer->mutex);
+ cpus_read_lock();
for_each_online_buffer_cpu(buffer, cpu) {
cpu_buffer = buffer->buffers[cpu];
@@ -5377,6 +5378,7 @@ void ring_buffer_reset_online_cpus(struct trace_buffer *buffer)
atomic_dec(&cpu_buffer->resize_disabled);
}
+ cpus_read_unlock();
mutex_unlock(&buffer->mutex);
}
--
2.18.0
Powered by blists - more mailing lists