[PATCH v4 11/18] ring-buffer: Add ring_buffer_read_remote_meta_page()
Vincent Donnefort <[email protected]> Tue, 4 Aug 2026 15:03:26 +0100
| Newsgroups | org.kernel.vger.linux-trace-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
In preparation for the introduction of a panic handler for trace remotes, add ring_buffer_read_remote_meta_page(). This is similar to ring_buffer_poll_remote, but it doesn't try to wake up readers and, in the !RING_BUFFER_ALL_CPUS case, uses panic-friendly locks. While at it, update trace_remote_has_cpu() to use this new function instead of ring_buffer_poll_remote(), avoiding unnecessary wakeups when verifying if a CPU buffer is active. Signed-off-by: Vincent Donnefort <[email protected]> diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 0670742b2d60..3c0de6593c81 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -299,6 +299,7 @@ struct ring_buffer_remote { void *priv; }; +int ring_buffer_read_remote_meta_page(struct trace_buffer *buffer, int cpu); int ring_buffer_poll_remote(struct trace_buffer *buffer, int cpu); struct trace_buffer * diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 239041704e4d..4bb1a7780860 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -6807,6 +6807,47 @@ bool ring_buffer_empty_cpu(struct trace_buffer *buffer, int cpu) } EXPORT_SYMBOL_GPL(ring_buffer_empty_cpu); +/** + * ring_buffer_read_remote_meta_page - read the meta page of a remote ring buffer + * @buffer: The ring buffer + * @cpu: The CPU buffer to read (or RING_BUFFER_ALL_CPUS) + * + * Returns: + * 0 on success, or -EINVAL if the CPU is not in the buffer's cpumask. + */ +int ring_buffer_read_remote_meta_page(struct trace_buffer *buffer, int cpu) +{ + struct ring_buffer_per_cpu *cpu_buffer; + + if (cpu != RING_BUFFER_ALL_CPUS) { + unsigned long flags; + bool dolock; + + if (!cpumask_test_cpu(cpu, buffer->cpumask)) + return -EINVAL; + + cpu_buffer = buffer->buffers[cpu]; + + local_irq_save(flags); + dolock = rb_reader_lock(cpu_buffer); + rb_read_remote_meta_page(cpu_buffer); + rb_reader_unlock(cpu_buffer, dolock); + local_irq_restore(flags); + return 0; + } + + guard(cpus_read_lock)(); + + for_each_buffer_cpu(buffer, cpu) { + cpu_buffer = buffer->buffers[cpu]; + + guard(raw_spinlock_irqsave)(&cpu_buffer->reader_lock); + rb_read_remote_meta_page(cpu_buffer); + } + + return 0; +} + int ring_buffer_poll_remote(struct trace_buffer *buffer, int cpu) { struct ring_buffer_per_cpu *cpu_buffer; diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 58a38f3d4902..2421550d5601 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -350,7 +350,7 @@ static bool trace_remote_has_cpu(struct trace_remote *remote, int cpu) if (cpu == RING_BUFFER_ALL_CPUS) return true; - return ring_buffer_poll_remote(remote->trace_buffer, cpu) == 0; + return ring_buffer_read_remote_meta_page(remote->trace_buffer, cpu) == 0; } static void __free_ring_buffer_iter(struct trace_remote_iterator *iter, int cpu) -- 2.55.0.571.g244d577d93-goog