]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Takenori Nagano <t-nagano@ah.jp.nec.com> |
2 | Subject: [PATCH] Add dump_after_notifier sysctl | |
3 | Patch-mainline: never | |
4 | References: 265764 | |
5 | ||
6 | This patch adds dump_after_notifier sysctl to execute kdump after the notifier | |
7 | call chain. This basically makes it possible to execute KDB before kdump. | |
8 | ||
9 | Signed-off-by: Takenori Nagano <t-nagano@ah.jp.nec.com> | |
10 | Acked-by: Bernhard Walle <bwalle@suse.de> | |
11 | ||
12 | --- | |
13 | include/linux/kexec.h | 2 ++ | |
14 | include/linux/sysctl.h | 1 + | |
15 | kernel/kexec.c | 29 +++++++++++++++++++++++++++++ | |
16 | kernel/panic.c | 5 ++++- | |
17 | kernel/sysctl_check.c | 1 + | |
18 | 5 files changed, 37 insertions(+), 1 deletion(-) | |
19 | ||
20 | --- a/include/linux/kexec.h | |
21 | +++ b/include/linux/kexec.h | |
22 | @@ -154,6 +154,7 @@ unsigned long paddr_vmcoreinfo_note(void | |
23 | ||
24 | extern struct kimage *kexec_image; | |
25 | extern struct kimage *kexec_crash_image; | |
26 | +extern int dump_after_notifier; | |
27 | ||
28 | #ifndef kexec_flush_icache_page | |
29 | #define kexec_flush_icache_page(page) | |
30 | @@ -208,5 +209,6 @@ struct pt_regs; | |
31 | struct task_struct; | |
32 | static inline void crash_kexec(struct pt_regs *regs) { } | |
33 | static inline int kexec_should_crash(struct task_struct *p) { return 0; } | |
34 | +#define dump_after_notifier 0 | |
35 | #endif /* CONFIG_KEXEC */ | |
36 | #endif /* LINUX_KEXEC_H */ | |
37 | --- a/include/linux/sysctl.h | |
38 | +++ b/include/linux/sysctl.h | |
39 | @@ -164,6 +164,7 @@ enum | |
40 | KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */ | |
41 | KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ | |
42 | KERN_KDB=77, /* int: kdb on/off */ | |
43 | + KERN_DUMP_AFTER_NOTIFIER=78, /* int: kdump after panic_notifier (SUSE only) */ | |
44 | }; | |
45 | ||
46 | ||
47 | --- a/kernel/kexec.c | |
48 | +++ b/kernel/kexec.c | |
49 | @@ -30,6 +30,7 @@ | |
50 | #include <linux/pm.h> | |
51 | #include <linux/cpu.h> | |
52 | #include <linux/console.h> | |
53 | +#include <linux/sysctl.h> | |
54 | ||
55 | #include <asm/page.h> | |
56 | #include <asm/uaccess.h> | |
57 | @@ -45,6 +46,7 @@ | |
58 | ||
59 | /* Per cpu memory for storing cpu states in case of system crash. */ | |
60 | note_buf_t* crash_notes; | |
61 | +int dump_after_notifier; | |
62 | ||
63 | /* vmcoreinfo stuff */ | |
64 | unsigned char vmcoreinfo_data[VMCOREINFO_BYTES]; | |
65 | @@ -1151,6 +1153,30 @@ void crash_save_cpu(struct pt_regs *regs | |
66 | final_note(buf); | |
67 | } | |
68 | ||
69 | +#ifdef CONFIG_SYSCTL | |
70 | +static ctl_table dump_after_notifier_table[] = { | |
71 | + { | |
72 | + .ctl_name = KERN_DUMP_AFTER_NOTIFIER, | |
73 | + .procname = "dump_after_notifier", | |
74 | + .data = &dump_after_notifier, | |
75 | + .maxlen = sizeof(int), | |
76 | + .mode = 0644, | |
77 | + .proc_handler = &proc_dointvec, | |
78 | + }, | |
79 | + { .ctl_name = 0 } | |
80 | +}; | |
81 | + | |
82 | +static ctl_table kexec_sys_table[] = { | |
83 | + { | |
84 | + .ctl_name = CTL_KERN, | |
85 | + .procname = "kernel", | |
86 | + .mode = 0555, | |
87 | + .child = dump_after_notifier_table, | |
88 | + }, | |
89 | + { .ctl_name = 0 } | |
90 | +}; | |
91 | +#endif | |
92 | + | |
93 | static int __init crash_notes_memory_init(void) | |
94 | { | |
95 | /* Allocate memory for saving cpu registers. */ | |
96 | @@ -1160,6 +1186,9 @@ static int __init crash_notes_memory_ini | |
97 | " states failed\n"); | |
98 | return -ENOMEM; | |
99 | } | |
100 | +#ifdef CONFIG_SYSCTL | |
101 | + register_sysctl_table(kexec_sys_table); | |
102 | +#endif | |
103 | return 0; | |
104 | } | |
105 | module_init(crash_notes_memory_init) | |
106 | --- a/kernel/panic.c | |
107 | +++ b/kernel/panic.c | |
108 | @@ -95,7 +95,8 @@ NORET_TYPE void panic(const char * fmt, | |
109 | * everything else. | |
110 | * Do we want to call this before we try to display a message? | |
111 | */ | |
112 | - crash_kexec(NULL); | |
113 | + if (!dump_after_notifier) | |
114 | + crash_kexec(NULL); | |
115 | ||
116 | #ifdef CONFIG_SMP | |
117 | /* | |
118 | @@ -108,6 +109,8 @@ NORET_TYPE void panic(const char * fmt, | |
119 | ||
120 | atomic_notifier_call_chain(&panic_notifier_list, 0, buf); | |
121 | ||
122 | + crash_kexec(NULL); | |
123 | + | |
124 | if (!panic_blink) | |
125 | panic_blink = no_blink; | |
126 | ||
127 | --- a/kernel/sysctl_check.c | |
128 | +++ b/kernel/sysctl_check.c | |
129 | @@ -106,6 +106,7 @@ static const struct trans_ctl_table tran | |
130 | { KERN_PANIC_ON_NMI, "panic_on_unrecovered_nmi" }, | |
131 | { KERN_SETUID_DUMPABLE, "suid_dumpable" }, | |
132 | { KERN_KDB, "kdb" }, | |
133 | + { KERN_DUMP_AFTER_NOTIFIER, "dump_after_notifier" }, | |
134 | {} | |
135 | }; | |
136 |