diff options
author | Petr Pavlu <petr.pavlu@suse.com> | 2024-10-15 14:27:46 +0300 |
---|---|---|
committer | Steven Rostedt (Google) <rostedt@goodmis.org> | 2024-10-19 18:12:01 +0300 |
commit | b237e1f7d2273fdcffac20100b72c002bdd770dd (patch) | |
tree | 4c1bcaf2bab53dd88f292b43701bd946ee356016 /drivers/cdx/controller/cdx_controller.c | |
parent | 09661f75e75cb6c1d2d8326a70c311d46729235f (diff) | |
download | linux-b237e1f7d2273fdcffac20100b72c002bdd770dd.tar.xz |
ring-buffer: Limit time with disabled interrupts in rb_check_pages()
The function rb_check_pages() validates the integrity of a specified
per-CPU tracing ring buffer. It does so by traversing the underlying
linked list and checking its next and prev links.
To guarantee that the list isn't modified during the check, a caller
typically needs to take cpu_buffer->reader_lock. This prevents the check
from running concurrently, for example, with a potential reader which
can make the list temporarily inconsistent when swapping its old reader
page into the buffer.
A problem with this approach is that the time when interrupts are
disabled is non-deterministic, dependent on the ring buffer size. This
particularly affects PREEMPT_RT because the reader_lock is a raw
spinlock which doesn't become sleepable on PREEMPT_RT kernels.
Modify the check so it still attempts to traverse the entire list, but
gives up the reader_lock between checking individual pages. Introduce
for this purpose a new variable ring_buffer_per_cpu.cnt which is bumped
any time the list is modified. The value is used by rb_check_pages() to
detect such a change and restart the check.
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://lore.kernel.org/20241015112810.27203-1-petr.pavlu@suse.com
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Diffstat (limited to 'drivers/cdx/controller/cdx_controller.c')
0 files changed, 0 insertions, 0 deletions