From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> mainline inclusion from mainline-v7.3-rc3 commit 815e07c8fe885a87751c2496a30ae0dcd4118210 category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9956 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- rb_wake_up_waiters() is a irq_work callback which is initialized with init_irq_work(). As such it will be invoked in thread context on PREEMPT_RT. Invoking the callback in IRQ context on PREEMPT_RT is not an option due its usage of wake_up_all(). Since this callback may run in thread context, it needs to acquire ring_buffer_per_cpu::reader_lock with disabling interrupts and may not assume that they are disabled. Use raw_spinlock_irqsave() to acquire ring_buffer_per_cpu::reader_lock. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260911102152.YEtwkBj9@linutronix.de Fixes: 68282dd930ea3 ("ring-buffer: Fix resetting of shortest_full") Reviewed-by: Vincent Donnefort <vdonnefort@google.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Conflicts: kernel/trace/ring_buffer.c [scope_guard is not widely used in this version, so use original raw_spin_lock_irqsave/irqrestore instead.] Signed-off-by: Tengda Wu <wutengda2@huawei.com> --- kernel/trace/ring_buffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 9a2c8727b033..91346d3a0f96 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -828,6 +828,7 @@ static __always_inline bool full_hit(struct trace_buffer *buffer, int cpu, int f static void rb_wake_up_waiters(struct irq_work *work) { struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work); + unsigned long flags; wake_up_all(&rbwork->waiters); if (rbwork->full_waiters_pending || rbwork->wakeup_full) { @@ -835,14 +836,13 @@ static void rb_wake_up_waiters(struct irq_work *work) struct ring_buffer_per_cpu *cpu_buffer = container_of(rbwork, struct ring_buffer_per_cpu, irq_work); - /* Called from interrupt context */ - raw_spin_lock(&cpu_buffer->reader_lock); + raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); rbwork->wakeup_full = false; rbwork->full_waiters_pending = false; /* Waking up all waiters, they will reset the shortest full */ cpu_buffer->shortest_full = 0; - raw_spin_unlock(&cpu_buffer->reader_lock); + raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); wake_up_all(&rbwork->full_waiters); } -- 2.34.1