summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2019-05-14 18:45:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-14 22:52:51 -0400
commitc39ea0b9dd24bf1bf2baa5cdbfa1905f3065347b (patch)
tree170d9527ad5151dc3eaee71bd1344d765a4d7fd3
parente178a5beb36960902379040ee0b667fb0a8eee93 (diff)
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>
-rw-r--r--drivers/tty/sysrq.c6
-rw-r--r--include/linux/printk.h2
-rw-r--r--kernel/panic.c3
-rw-r--r--kernel/printk/printk.c10
4 files changed, 21 insertions, 0 deletions
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 59e82e6d776d..573b2055173c 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -527,8 +527,12 @@ void __handle_sysrq(int key, bool check_mask)
527{ 527{
528 struct sysrq_key_op *op_p; 528 struct sysrq_key_op *op_p;
529 int orig_log_level; 529 int orig_log_level;
530 int orig_suppress_printk;
530 int i; 531 int i;
531 532
533 orig_suppress_printk = suppress_printk;
534 suppress_printk = 0;
535
532 rcu_sysrq_start(); 536 rcu_sysrq_start();
533 rcu_read_lock(); 537 rcu_read_lock();
534 /* 538 /*
@@ -574,6 +578,8 @@ void __handle_sysrq(int key, bool check_mask)
574 } 578 }
575 rcu_read_unlock(); 579 rcu_read_unlock();
576 rcu_sysrq_end(); 580 rcu_sysrq_end();
581
582 suppress_printk = orig_suppress_printk;
577} 583}
578 584
579void handle_sysrq(int key) 585void handle_sysrq(int key)
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 84ea4d094af3..cefd374c47b1 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -82,6 +82,8 @@ static inline void console_verbose(void)
82extern char devkmsg_log_str[]; 82extern char devkmsg_log_str[];
83struct ctl_table; 83struct ctl_table;
84 84
85extern int suppress_printk;
86
85struct va_format { 87struct va_format {
86 const char *fmt; 88 const char *fmt;
87 va_list *va; 89 va_list *va;
diff --git a/kernel/panic.c b/kernel/panic.c
index c1fcaad337b7..a6145050a8da 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -321,6 +321,9 @@ void panic(const char *fmt, ...)
321 disabled_wait(); 321 disabled_wait();
322#endif 322#endif
323 pr_emerg("---[ end Kernel panic - not syncing: %s ]---\n", buf); 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 local_irq_enable(); 327 local_irq_enable();
325 for (i = 0; ; i += PANIC_TIMER_STEP) { 328 for (i = 0; ; i += PANIC_TIMER_STEP) {
326 touch_softlockup_watchdog(); 329 touch_softlockup_watchdog();
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 02ca827b8fac..17102fd4c136 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -86,6 +86,12 @@ static DEFINE_SEMAPHORE(console_sem);
86struct console *console_drivers; 86struct console *console_drivers;
87EXPORT_SYMBOL_GPL(console_drivers); 87EXPORT_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 */
93int __read_mostly suppress_printk;
94
89#ifdef CONFIG_LOCKDEP 95#ifdef CONFIG_LOCKDEP
90static struct lockdep_map console_lock_dep_map = { 96static struct lockdep_map console_lock_dep_map = {
91 .name = "console_lock" 97 .name = "console_lock"
@@ -1943,6 +1949,10 @@ asmlinkage int vprintk_emit(int facility, int level,
1943 unsigned long flags; 1949 unsigned long flags;
1944 u64 curr_log_seq; 1950 u64 curr_log_seq;
1945 1951
1952 /* Suppress unimportant messages after panic happens */
1953 if (unlikely(suppress_printk))
1954 return 0;
1955
1946 if (level == LOGLEVEL_SCHED) { 1956 if (level == LOGLEVEL_SCHED) {
1947 level = LOGLEVEL_DEFAULT; 1957 level = LOGLEVEL_DEFAULT;
1948 in_sched = true; 1958 in_sched = true;