Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

panic: avoid the extra noise dmesg

When kernel panic happens, it will first print the panic call stack,
then the ending msg like:

[ 35.743249] ---[ end Kernel panic - not syncing: Fatal exception
[ 35.749975] ------------[ cut here ]------------

The above message are very useful for debugging.

But if system is configured to not reboot on panic, say the
"panic_timeout" parameter equals 0, it will likely print out many noisy
message like WARN() call stack for each and every CPU except the panic
one, messages like below:

WARNING: CPU: 1 PID: 280 at kernel/sched/core.c:1198 set_task_cpu+0x183/0x190
Call Trace:
<IRQ>
try_to_wake_up
default_wake_function
autoremove_wake_function
__wake_up_common
__wake_up_common_lock
__wake_up
wake_up_klogd_work_func
irq_work_run_list
irq_work_tick
update_process_times
tick_sched_timer
__hrtimer_run_queues
hrtimer_interrupt
smp_apic_timer_interrupt
apic_timer_interrupt

For people working in console mode, the screen will first show the panic
call stack, but immediately overridden by these noisy extra messages,
which makes debugging much more difficult, as the original context gets
lost on screen.

Also these noisy messages will confuse some users, as I have seen many bug
reporters posted the noisy message into bugzilla, instead of the real
panic call stack and context.

Adding a flag "suppress_printk" which gets set in panic() to avoid those
noisy messages, without changing current kernel behavior that both panic
blinking and sysrq magic key can work as is, suggested by Petr Mladek.

To verify this, make sure kernel is not configured to reboot on panic and
in console
# echo c > /proc/sysrq-trigger
to see if console only prints out the panic call stack.

Link: http://lkml.kernel.org/r/1551430186-24169-1-git-send-email-feng.tang@intel.com
Signed-off-by: Feng Tang <feng.tang@intel.com>
Suggested-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Acked-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Sasha Levin <sashal@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Feng Tang and committed by
Linus Torvalds
c39ea0b9 e178a5be

+21
+6
drivers/tty/sysrq.c
··· 527 527 { 528 528 struct sysrq_key_op *op_p; 529 529 int orig_log_level; 530 + int orig_suppress_printk; 530 531 int i; 532 + 533 + orig_suppress_printk = suppress_printk; 534 + suppress_printk = 0; 531 535 532 536 rcu_sysrq_start(); 533 537 rcu_read_lock(); ··· 578 574 } 579 575 rcu_read_unlock(); 580 576 rcu_sysrq_end(); 577 + 578 + suppress_printk = orig_suppress_printk; 581 579 } 582 580 583 581 void handle_sysrq(int key)
+2
include/linux/printk.h
··· 82 82 extern char devkmsg_log_str[]; 83 83 struct ctl_table; 84 84 85 + extern int suppress_printk; 86 + 85 87 struct va_format { 86 88 const char *fmt; 87 89 va_list *va;
+3
kernel/panic.c
··· 321 321 disabled_wait(); 322 322 #endif 323 323 pr_emerg("---[ end Kernel panic - not syncing: %s ]---\n", buf); 324 + 325 + /* Do not scroll important messages printed above */ 326 + suppress_printk = 1; 324 327 local_irq_enable(); 325 328 for (i = 0; ; i += PANIC_TIMER_STEP) { 326 329 touch_softlockup_watchdog();
+10
kernel/printk/printk.c
··· 86 86 struct console *console_drivers; 87 87 EXPORT_SYMBOL_GPL(console_drivers); 88 88 89 + /* 90 + * System may need to suppress printk message under certain 91 + * circumstances, like after kernel panic happens. 92 + */ 93 + int __read_mostly suppress_printk; 94 + 89 95 #ifdef CONFIG_LOCKDEP 90 96 static struct lockdep_map console_lock_dep_map = { 91 97 .name = "console_lock" ··· 1948 1942 bool in_sched = false, pending_output; 1949 1943 unsigned long flags; 1950 1944 u64 curr_log_seq; 1945 + 1946 + /* Suppress unimportant messages after panic happens */ 1947 + if (unlikely(suppress_printk)) 1948 + return 0; 1951 1949 1952 1950 if (level == LOGLEVEL_SCHED) { 1953 1951 level = LOGLEVEL_DEFAULT;