Skip to content

Commit

Permalink
panic: add an option to replay all the printk message in buffer
Browse files Browse the repository at this point in the history
Currently on panic, kernel will lower the loglevel and print out pending
printk msg only with console_flush_on_panic().

Add an option for users to configure the "panic_print" to replay all
dmesg in buffer, some of which they may have never seen due to the
loglevel setting, which will help panic debugging .

[[email protected]: keep the original console_flush_on_panic() inside panic()]
  Link: http://lkml.kernel.org/r/[email protected]
[[email protected]: use logbuf lock to protect the console log index]
  Link: http://lkml.kernel.org/r/[email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Feng Tang <[email protected]>
Reviewed-by: Petr Mladek <[email protected]>
Cc: Aaro Koskinen <[email protected]>
Cc: Petr Mladek <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Sergey Senozhatsky <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Borislav Petkov <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
ftang1 authored and torvalds committed May 18, 2019
1 parent 5d59aa8 commit de6da1e
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 4 deletions.
1 change: 1 addition & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3212,6 +3212,7 @@
bit 2: print timer info
bit 3: print locks info if CONFIG_LOCKDEP is on
bit 4: print ftrace buffer
bit 5: print all printk messages in buffer

panic_on_warn panic() instead of WARN(). Useful to cause kdump
on a WARN().
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ extern void panic_flush_kmsg_end(void)
kmsg_dump(KMSG_DUMP_PANIC);
bust_spinlocks(0);
debug_locks_off();
console_flush_on_panic();
console_flush_on_panic(CONSOLE_FLUSH_PENDING);
}

static unsigned long oops_begin(struct pt_regs *regs)
Expand Down
7 changes: 6 additions & 1 deletion include/linux/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ struct console {
extern int console_set_on_cmdline;
extern struct console *early_console;

enum con_flush_mode {
CONSOLE_FLUSH_PENDING,
CONSOLE_REPLAY_ALL,
};

extern int add_preferred_console(char *name, int idx, char *options);
extern void register_console(struct console *);
extern int unregister_console(struct console *);
Expand All @@ -175,7 +180,7 @@ extern int console_trylock(void);
extern void console_unlock(void);
extern void console_conditional_schedule(void);
extern void console_unblank(void);
extern void console_flush_on_panic(void);
extern void console_flush_on_panic(enum con_flush_mode mode);
extern struct tty_driver *console_device(int *);
extern void console_stop(struct console *);
extern void console_start(struct console *);
Expand Down
6 changes: 5 additions & 1 deletion kernel/panic.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ EXPORT_SYMBOL_GPL(panic_timeout);
#define PANIC_PRINT_TIMER_INFO 0x00000004
#define PANIC_PRINT_LOCK_INFO 0x00000008
#define PANIC_PRINT_FTRACE_INFO 0x00000010
#define PANIC_PRINT_ALL_PRINTK_MSG 0x00000020
unsigned long panic_print;

ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
Expand Down Expand Up @@ -134,6 +135,9 @@ EXPORT_SYMBOL(nmi_panic);

static void panic_print_sys_info(void)
{
if (panic_print & PANIC_PRINT_ALL_PRINTK_MSG)
console_flush_on_panic(CONSOLE_REPLAY_ALL);

if (panic_print & PANIC_PRINT_TASK_INFO)
show_state();

Expand Down Expand Up @@ -277,7 +281,7 @@ void panic(const char *fmt, ...)
* panic() is not being callled from OOPS.
*/
debug_locks_off();
console_flush_on_panic();
console_flush_on_panic(CONSOLE_FLUSH_PENDING);

panic_print_sys_info();

Expand Down
12 changes: 11 additions & 1 deletion kernel/printk/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2535,10 +2535,11 @@ void console_unblank(void)

/**
* console_flush_on_panic - flush console content on panic
* @mode: flush all messages in buffer or just the pending ones
*
* Immediately output all pending messages no matter what.
*/
void console_flush_on_panic(void)
void console_flush_on_panic(enum con_flush_mode mode)
{
/*
* If someone else is holding the console lock, trylock will fail
Expand All @@ -2549,6 +2550,15 @@ void console_flush_on_panic(void)
*/
console_trylock();
console_may_schedule = 0;

if (mode == CONSOLE_REPLAY_ALL) {
unsigned long flags;

logbuf_lock_irqsave(flags);
console_seq = log_first_seq;
console_idx = log_first_idx;
logbuf_unlock_irqrestore(flags);
}
console_unlock();
}

Expand Down

0 comments on commit de6da1e

Please sign in to comment.