aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt1
-rw-r--r--arch/powerpc/kernel/traps.c2
-rw-r--r--include/linux/console.h7
-rw-r--r--kernel/panic.c6
-rw-r--r--kernel/printk/printk.c12
5 files changed, 24 insertions, 4 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 52e6fbb042cc..138f6664b2e2 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3212,6 +3212,7 @@
3212 bit 2: print timer info 3212 bit 2: print timer info
3213 bit 3: print locks info if CONFIG_LOCKDEP is on 3213 bit 3: print locks info if CONFIG_LOCKDEP is on
3214 bit 4: print ftrace buffer 3214 bit 4: print ftrace buffer
3215 bit 5: print all printk messages in buffer
3215 3216
3216 panic_on_warn panic() instead of WARN(). Useful to cause kdump 3217 panic_on_warn panic() instead of WARN(). Useful to cause kdump
3217 on a WARN(). 3218 on a WARN().
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 665f294725cb..83e59fdaa62d 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -179,7 +179,7 @@ extern void panic_flush_kmsg_end(void)
179 kmsg_dump(KMSG_DUMP_PANIC); 179 kmsg_dump(KMSG_DUMP_PANIC);
180 bust_spinlocks(0); 180 bust_spinlocks(0);
181 debug_locks_off(); 181 debug_locks_off();
182 console_flush_on_panic(); 182 console_flush_on_panic(CONSOLE_FLUSH_PENDING);
183} 183}
184 184
185static unsigned long oops_begin(struct pt_regs *regs) 185static unsigned long oops_begin(struct pt_regs *regs)
diff --git a/include/linux/console.h b/include/linux/console.h
index ec9bdb3d7bab..d09951d5a94e 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -166,6 +166,11 @@ struct console {
166extern int console_set_on_cmdline; 166extern int console_set_on_cmdline;
167extern struct console *early_console; 167extern struct console *early_console;
168 168
169enum con_flush_mode {
170 CONSOLE_FLUSH_PENDING,
171 CONSOLE_REPLAY_ALL,
172};
173
169extern int add_preferred_console(char *name, int idx, char *options); 174extern int add_preferred_console(char *name, int idx, char *options);
170extern void register_console(struct console *); 175extern void register_console(struct console *);
171extern int unregister_console(struct console *); 176extern int unregister_console(struct console *);
@@ -175,7 +180,7 @@ extern int console_trylock(void);
175extern void console_unlock(void); 180extern void console_unlock(void);
176extern void console_conditional_schedule(void); 181extern void console_conditional_schedule(void);
177extern void console_unblank(void); 182extern void console_unblank(void);
178extern void console_flush_on_panic(void); 183extern void console_flush_on_panic(enum con_flush_mode mode);
179extern struct tty_driver *console_device(int *); 184extern struct tty_driver *console_device(int *);
180extern void console_stop(struct console *); 185extern void console_stop(struct console *);
181extern void console_start(struct console *); 186extern void console_start(struct console *);
diff --git a/kernel/panic.c b/kernel/panic.c
index 8779d64bace0..b4543a31a495 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -51,6 +51,7 @@ EXPORT_SYMBOL_GPL(panic_timeout);
51#define PANIC_PRINT_TIMER_INFO 0x00000004 51#define PANIC_PRINT_TIMER_INFO 0x00000004
52#define PANIC_PRINT_LOCK_INFO 0x00000008 52#define PANIC_PRINT_LOCK_INFO 0x00000008
53#define PANIC_PRINT_FTRACE_INFO 0x00000010 53#define PANIC_PRINT_FTRACE_INFO 0x00000010
54#define PANIC_PRINT_ALL_PRINTK_MSG 0x00000020
54unsigned long panic_print; 55unsigned long panic_print;
55 56
56ATOMIC_NOTIFIER_HEAD(panic_notifier_list); 57ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
@@ -134,6 +135,9 @@ EXPORT_SYMBOL(nmi_panic);
134 135
135static void panic_print_sys_info(void) 136static void panic_print_sys_info(void)
136{ 137{
138 if (panic_print & PANIC_PRINT_ALL_PRINTK_MSG)
139 console_flush_on_panic(CONSOLE_REPLAY_ALL);
140
137 if (panic_print & PANIC_PRINT_TASK_INFO) 141 if (panic_print & PANIC_PRINT_TASK_INFO)
138 show_state(); 142 show_state();
139 143
@@ -277,7 +281,7 @@ void panic(const char *fmt, ...)
277 * panic() is not being callled from OOPS. 281 * panic() is not being callled from OOPS.
278 */ 282 */
279 debug_locks_off(); 283 debug_locks_off();
280 console_flush_on_panic(); 284 console_flush_on_panic(CONSOLE_FLUSH_PENDING);
281 285
282 panic_print_sys_info(); 286 panic_print_sys_info();
283 287
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 17102fd4c136..a6e06fe38e41 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2535,10 +2535,11 @@ void console_unblank(void)
2535 2535
2536/** 2536/**
2537 * console_flush_on_panic - flush console content on panic 2537 * console_flush_on_panic - flush console content on panic
2538 * @mode: flush all messages in buffer or just the pending ones
2538 * 2539 *
2539 * Immediately output all pending messages no matter what. 2540 * Immediately output all pending messages no matter what.
2540 */ 2541 */
2541void console_flush_on_panic(void) 2542void console_flush_on_panic(enum con_flush_mode mode)
2542{ 2543{
2543 /* 2544 /*
2544 * If someone else is holding the console lock, trylock will fail 2545 * If someone else is holding the console lock, trylock will fail
@@ -2549,6 +2550,15 @@ void console_flush_on_panic(void)
2549 */ 2550 */
2550 console_trylock(); 2551 console_trylock();
2551 console_may_schedule = 0; 2552 console_may_schedule = 0;
2553
2554 if (mode == CONSOLE_REPLAY_ALL) {
2555 unsigned long flags;
2556
2557 logbuf_lock_irqsave(flags);
2558 console_seq = log_first_seq;
2559 console_idx = log_first_idx;
2560 logbuf_unlock_irqrestore(flags);
2561 }
2552 console_unlock(); 2562 console_unlock();
2553} 2563}
2554 2564