[patch] add kdump_after_notifier

Takenori Nagano t-nagano at ah.jp.nec.com
Thu Jul 19 08:15:12 EDT 2007


Hi,

In latest kernel, we can't use panic_notifier_list if kdump is enabled.
panic_notifier_list is very useful function for debug, failover, etc...

So this patch adds a control file /proc/sys/kernel/dump_after_notifier
and resolves a problem users can not use both kdump and panic_notifier_list
at the same time.

kdump_after_notifier = 0
 -> panic()
    -> crash_kexec(NULL)

kdump_after_notifier = 1
 -> panic()
    -> atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
    -> crash_kexec(NULL)


Signed-off-by: Takenori Nagano <t-nagano at ah.jp.nec.com>
Signed-off-by: Kazuto Miyoshi <k-miyoshi at cb.jp.nec.com>
---

diff -uprN linux-2.6.22.orig/include/linux/kexec.h
linux-2.6.22/include/linux/kexec.h
--- linux-2.6.22.orig/include/linux/kexec.h	2007-07-09 08:32:17.000000000 +0900
+++ linux-2.6.22/include/linux/kexec.h	2007-07-19 18:55:04.236000000 +0900
@@ -123,6 +123,7 @@ int kexec_should_crash(struct task_struc
 void crash_save_cpu(struct pt_regs *regs, int cpu);
 extern struct kimage *kexec_image;
 extern struct kimage *kexec_crash_image;
+extern int kdump_after_notifier;

 #ifndef kexec_flush_icache_page
 #define kexec_flush_icache_page(page)
@@ -160,5 +161,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 kdump_after_notifier 0
 #endif /* CONFIG_KEXEC */
 #endif /* LINUX_KEXEC_H */
diff -uprN linux-2.6.22.orig/include/linux/sysctl.h
linux-2.6.22/include/linux/sysctl.h
--- linux-2.6.22.orig/include/linux/sysctl.h	2007-07-09 08:32:17.000000000 +0900
+++ linux-2.6.22/include/linux/sysctl.h	2007-07-19 18:55:04.260000000 +0900
@@ -165,6 +165,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_KDUMP_AFTER_NOTIFIER=77, /* int: kdump after panic_notifier */
 };


diff -uprN linux-2.6.22.orig/kernel/kexec.c linux-2.6.22/kernel/kexec.c
--- linux-2.6.22.orig/kernel/kexec.c	2007-07-09 08:32:17.000000000 +0900
+++ linux-2.6.22/kernel/kexec.c	2007-07-19 18:55:04.304000000 +0900
@@ -22,6 +22,7 @@
 #include <linux/hardirq.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/sysctl.h>

 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -31,6 +32,7 @@

 /* Per cpu memory for storing cpu states in case of system crash. */
 note_buf_t* crash_notes;
+int kdump_after_notifier;

 /* Location of the reserved area for the crash kernel */
 struct resource crashk_res = {
@@ -1123,6 +1125,30 @@ void crash_save_cpu(struct pt_regs *regs
 	final_note(buf);
 }

+#ifdef CONFIG_SYSCTL
+static ctl_table kdump_after_notifier_table[] = {
+	{
+		.ctl_name = KERN_KDUMP_AFTER_NOTIFIER,
+		.procname = "kdump_after_notifier",
+		.data = &kdump_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 = kdump_after_notifier_table,
+	},
+	{ .ctl_name = 0 }
+};
+#endif
+
 static int __init crash_notes_memory_init(void)
 {
 	/* Allocate memory for saving cpu registers. */
@@ -1132,6 +1158,9 @@ static int __init crash_notes_memory_ini
 		" states failed\n");
 		return -ENOMEM;
 	}
+#ifdef CONFIG_SYSCTL
+	register_sysctl_table(kexec_sys_table, 0);
+#endif
 	return 0;
 }
 module_init(crash_notes_memory_init)
diff -uprN linux-2.6.22.orig/kernel/panic.c linux-2.6.22/kernel/panic.c
--- linux-2.6.22.orig/kernel/panic.c	2007-07-09 08:32:17.000000000 +0900
+++ linux-2.6.22/kernel/panic.c	2007-07-19 18:55:04.340000000 +0900
@@ -85,7 +85,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 (!kdump_after_notifier)
+		crash_kexec(NULL);

 #ifdef CONFIG_SMP
 	/*
@@ -98,6 +99,8 @@ NORET_TYPE void panic(const char * fmt,

 	atomic_notifier_call_chain(&panic_notifier_list, 0, buf);

+	crash_kexec(NULL);
+
 	if (!panic_blink)
 		panic_blink = no_blink;






More information about the kexec mailing list