Skip to content

Commit 5d5e452

Browse files
npigginpmladek
authored andcommitted
printk: restore flushing of NMI buffers on remote CPUs after NMI backtraces
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: 93d102f ("printk: remove safe buffers") Cc: [email protected] # 5.15 Signed-off-by: Nicholas Piggin <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Reviewed-by: John Ogness <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 26d1982 commit 5d5e452

File tree

4 files changed

+21
-0
lines changed

4 files changed

+21
-0
lines changed

arch/powerpc/kernel/watchdog.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ static void watchdog_smp_panic(int cpu, u64 tb)
186186
if (sysctl_hardlockup_all_cpu_backtrace)
187187
trigger_allbutself_cpu_backtrace();
188188

189+
/*
190+
* Force flush any remote buffers that might be stuck in IRQ context
191+
* and therefore could not run their irq_work.
192+
*/
193+
printk_trigger_flush();
194+
189195
if (hardlockup_panic)
190196
nmi_panic(NULL, "Hard LOCKUP");
191197

include/linux/printk.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ void dump_stack_print_info(const char *log_lvl);
206206
void show_regs_print_info(const char *log_lvl);
207207
extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold;
208208
extern asmlinkage void dump_stack(void) __cold;
209+
void printk_trigger_flush(void);
209210
#else
210211
static inline __printf(1, 0)
211212
int vprintk(const char *s, va_list args)
@@ -282,6 +283,9 @@ static inline void dump_stack_lvl(const char *log_lvl)
282283
static inline void dump_stack(void)
283284
{
284285
}
286+
static inline void printk_trigger_flush(void)
287+
{
288+
}
285289
#endif
286290

287291
#ifdef CONFIG_SMP

kernel/printk/printk.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,6 +3261,11 @@ void defer_console_output(void)
32613261
preempt_enable();
32623262
}
32633263

3264+
void printk_trigger_flush(void)
3265+
{
3266+
defer_console_output();
3267+
}
3268+
32643269
int vprintk_deferred(const char *fmt, va_list args)
32653270
{
32663271
int r;

lib/nmi_backtrace.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ void nmi_trigger_cpumask_backtrace(const cpumask_t *mask,
7575
touch_softlockup_watchdog();
7676
}
7777

78+
/*
79+
* Force flush any remote buffers that might be stuck in IRQ context
80+
* and therefore could not run their irq_work.
81+
*/
82+
printk_trigger_flush();
83+
7884
clear_bit_unlock(0, &backtrace_flag);
7985
put_cpu();
8086
}

0 commit comments

Comments
 (0)