137 lines
3.8 KiB
Diff
137 lines
3.8 KiB
Diff
|
From: Takenori Nagano <t-nagano@ah.jp.nec.com>
|
||
|
Subject: [PATCH] Add dump_after_notifier sysctl
|
||
|
Patch-mainline: never
|
||
|
References: 265764
|
||
|
|
||
|
This patch adds dump_after_notifier sysctl to execute kdump after the notifier
|
||
|
call chain. This basically makes it possible to execute KDB before kdump.
|
||
|
|
||
|
Signed-off-by: Takenori Nagano <t-nagano@ah.jp.nec.com>
|
||
|
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||
|
|
||
|
---
|
||
|
include/linux/kexec.h | 2 ++
|
||
|
include/linux/sysctl.h | 1 +
|
||
|
kernel/kexec.c | 29 +++++++++++++++++++++++++++++
|
||
|
kernel/panic.c | 5 ++++-
|
||
|
kernel/sysctl_check.c | 1 +
|
||
|
5 files changed, 37 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/include/linux/kexec.h
|
||
|
+++ b/include/linux/kexec.h
|
||
|
@@ -158,6 +158,7 @@ unsigned long paddr_vmcoreinfo_note(void
|
||
|
|
||
|
extern struct kimage *kexec_image;
|
||
|
extern struct kimage *kexec_crash_image;
|
||
|
+extern int dump_after_notifier;
|
||
|
|
||
|
#ifndef kexec_flush_icache_page
|
||
|
#define kexec_flush_icache_page(page)
|
||
|
@@ -212,5 +213,6 @@ struct pt_regs;
|
||
|
struct task_struct;
|
||
|
static inline void crash_kexec(struct pt_regs *regs) { }
|
||
|
static inline int kexec_should_crash(struct task_struct *p) { return 0; }
|
||
|
+#define dump_after_notifier 0
|
||
|
#endif /* CONFIG_KEXEC */
|
||
|
#endif /* LINUX_KEXEC_H */
|
||
|
--- a/include/linux/sysctl.h
|
||
|
+++ b/include/linux/sysctl.h
|
||
|
@@ -162,6 +162,7 @@ enum
|
||
|
KERN_MAX_LOCK_DEPTH=74,
|
||
|
KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
|
||
|
KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
|
||
|
+ KERN_DUMP_AFTER_NOTIFIER=78, /* int: kdump after panic_notifier (SUSE only) */
|
||
|
KERN_PANIC_ON_IO_NMI=79, /* int: whether we will panic on an io NMI */
|
||
|
};
|
||
|
|
||
|
--- a/kernel/kexec.c
|
||
|
+++ b/kernel/kexec.c
|
||
|
@@ -31,6 +31,7 @@
|
||
|
#include <linux/cpu.h>
|
||
|
#include <linux/console.h>
|
||
|
#include <linux/vmalloc.h>
|
||
|
+#include <linux/sysctl.h>
|
||
|
|
||
|
#include <asm/page.h>
|
||
|
#include <asm/uaccess.h>
|
||
|
@@ -46,6 +47,7 @@
|
||
|
|
||
|
/* Per cpu memory for storing cpu states in case of system crash. */
|
||
|
note_buf_t* crash_notes;
|
||
|
+int dump_after_notifier;
|
||
|
|
||
|
/* vmcoreinfo stuff */
|
||
|
static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
|
||
|
@@ -1152,6 +1154,30 @@ void crash_save_cpu(struct pt_regs *regs
|
||
|
final_note(buf);
|
||
|
}
|
||
|
|
||
|
+#ifdef CONFIG_SYSCTL
|
||
|
+static ctl_table dump_after_notifier_table[] = {
|
||
|
+ {
|
||
|
+ .ctl_name = KERN_DUMP_AFTER_NOTIFIER,
|
||
|
+ .procname = "dump_after_notifier",
|
||
|
+ .data = &dump_after_notifier,
|
||
|
+ .maxlen = sizeof(int),
|
||
|
+ .mode = 0644,
|
||
|
+ .proc_handler = &proc_dointvec,
|
||
|
+ },
|
||
|
+ { .ctl_name = 0 }
|
||
|
+};
|
||
|
+
|
||
|
+static ctl_table kexec_sys_table[] = {
|
||
|
+ {
|
||
|
+ .ctl_name = CTL_KERN,
|
||
|
+ .procname = "kernel",
|
||
|
+ .mode = 0555,
|
||
|
+ .child = dump_after_notifier_table,
|
||
|
+ },
|
||
|
+ { .ctl_name = 0 }
|
||
|
+};
|
||
|
+#endif
|
||
|
+
|
||
|
static int __init crash_notes_memory_init(void)
|
||
|
{
|
||
|
/* Allocate memory for saving cpu registers. */
|
||
|
@@ -1161,6 +1187,9 @@ static int __init crash_notes_memory_ini
|
||
|
" states failed\n");
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
+#ifdef CONFIG_SYSCTL
|
||
|
+ register_sysctl_table(kexec_sys_table);
|
||
|
+#endif
|
||
|
return 0;
|
||
|
}
|
||
|
module_init(crash_notes_memory_init)
|
||
|
--- a/kernel/panic.c
|
||
|
+++ b/kernel/panic.c
|
||
|
@@ -87,7 +87,8 @@ NORET_TYPE void panic(const char * fmt,
|
||
|
* everything else.
|
||
|
* Do we want to call this before we try to display a message?
|
||
|
*/
|
||
|
- crash_kexec(NULL);
|
||
|
+ if (!dump_after_notifier)
|
||
|
+ crash_kexec(NULL);
|
||
|
|
||
|
/*
|
||
|
* Note smp_send_stop is the usual smp shutdown function, which
|
||
|
@@ -98,6 +99,8 @@ NORET_TYPE void panic(const char * fmt,
|
||
|
|
||
|
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
|
||
|
|
||
|
+ crash_kexec(NULL);
|
||
|
+
|
||
|
bust_spinlocks(0);
|
||
|
|
||
|
if (!panic_blink)
|
||
|
--- a/kernel/sysctl_check.c
|
||
|
+++ b/kernel/sysctl_check.c
|
||
|
@@ -106,6 +106,7 @@ static const struct trans_ctl_table tran
|
||
|
{ KERN_PANIC_ON_NMI, "panic_on_unrecovered_nmi" },
|
||
|
{ KERN_PANIC_ON_IO_NMI, "panic_on_io_nmi" },
|
||
|
{ KERN_SETUID_DUMPABLE, "suid_dumpable" },
|
||
|
+ { KERN_DUMP_AFTER_NOTIFIER, "dump_after_notifier" },
|
||
|
{}
|
||
|
};
|
||
|
|