]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
printk: restore flushing of NMI buffers on remote CPUs after NMI backtraces
authorNicholas Piggin <npiggin@gmail.com>
Sun, 7 Nov 2021 04:51:16 +0000 (14:51 +1000)
committerAndrea Righi <andrea.righi@canonical.com>
Tue, 4 Jan 2022 08:48:53 +0000 (09:48 +0100)
BugLink: https://bugs.launchpad.net/bugs/1952579
commit 5d5e4522a7f404d1a96fd6c703989d32a9c9568d upstream.

printk from NMI context relies on irq work being raised on the local CPU
to print to console. This can be a problem if the NMI was raised by a
lockup detector to print lockup stack and regs, because the CPU may not
enable irqs (because it is locked up).

Introduce printk_trigger_flush() that can be called another CPU to try
to get those messages to the console, call that where printk_safe_flush
was previously called.

Fixes: 93d102f094be ("printk: remove safe buffers")
Cc: stable@vger.kernel.org # 5.15
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20211107045116.1754411-1-npiggin@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
arch/powerpc/kernel/watchdog.c
include/linux/printk.h
kernel/printk/printk.c
lib/nmi_backtrace.c

index f9ea0e5357f9290a15c7c843a6b2ce45129b74bc..3fa6d240bade21c0e51002f48956e12db9003263 100644 (file)
@@ -187,6 +187,12 @@ static void watchdog_smp_panic(int cpu, u64 tb)
        if (sysctl_hardlockup_all_cpu_backtrace)
                trigger_allbutself_cpu_backtrace();
 
+       /*
+        * Force flush any remote buffers that might be stuck in IRQ context
+        * and therefore could not run their irq_work.
+        */
+       printk_trigger_flush();
+
        if (hardlockup_panic)
                nmi_panic(NULL, "Hard LOCKUP");
 
index 85b656f82d752ecf18d67a693e4de0201ddd9a2e..9497f6b983399ac0cf6a21d5e4b57f9e144e2d74 100644 (file)
@@ -198,6 +198,7 @@ void dump_stack_print_info(const char *log_lvl);
 void show_regs_print_info(const char *log_lvl);
 extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold;
 extern asmlinkage void dump_stack(void) __cold;
+void printk_trigger_flush(void);
 #else
 static inline __printf(1, 0)
 int vprintk(const char *s, va_list args)
@@ -274,6 +275,9 @@ static inline void dump_stack_lvl(const char *log_lvl)
 static inline void dump_stack(void)
 {
 }
+static inline void printk_trigger_flush(void)
+{
+}
 #endif
 
 #ifdef CONFIG_SMP
index a8d0a58deebc708b08574bee0e29bbbe5ff961b1..99221b016c68b9435ef999f36a2b337e4c71a520 100644 (file)
@@ -3252,6 +3252,11 @@ void defer_console_output(void)
        preempt_enable();
 }
 
+void printk_trigger_flush(void)
+{
+       defer_console_output();
+}
+
 int vprintk_deferred(const char *fmt, va_list args)
 {
        int r;
index f9e89001b52ebdc08e3f5e6afa8c44fbf576844d..199ab201d5019c7c216f4db0f32da947e1d4503c 100644 (file)
@@ -75,6 +75,12 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
                touch_softlockup_watchdog();
        }
 
+       /*
+        * Force flush any remote buffers that might be stuck in IRQ context
+        * and therefore could not run their irq_work.
+        */
+       printk_trigger_flush();
+
        clear_bit_unlock(0, &backtrace_flag);
        put_cpu();
 }