diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-05-12 15:21:04 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-25 00:34:44 -0400 |
commit | 9c44bc03fff44ff04237a7d92e35304a0e50c331 (patch) | |
tree | 64704ff78933a3a3bd8549801308d0557c02980d | |
parent | 75d3bce2fc0a80f435fe12f2c9ed2632c8ac29e4 (diff) |
softlockup: allow panic on lockup
allow users to configure the softlockup detector to generate a panic
instead of a warning message.
high-availability systems might opt for this strict method (combined
with panic_timeout= boot option/sysctl), instead of generating
softlockup warnings ad infinitum.
also, automated tests work better if the system reboots reliably (into
a safe kernel) in case of a lockup.
The full spectrum of configurability is supported: boot option, sysctl
option and Kconfig option.
it's default-disabled.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | Documentation/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | include/linux/sched.h | 3 | ||||
-rw-r--r-- | kernel/softlockup.c | 21 | ||||
-rw-r--r-- | kernel/sysctl.c | 11 | ||||
-rw-r--r-- | lib/Kconfig.debug | 26 |
5 files changed, 62 insertions, 2 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e07c432c731f..042588fa12e5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1971,6 +1971,9 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1971 | 1971 | ||
1972 | snd-ymfpci= [HW,ALSA] | 1972 | snd-ymfpci= [HW,ALSA] |
1973 | 1973 | ||
1974 | softlockup_panic= | ||
1975 | [KNL] Should the soft-lockup detector generate panics. | ||
1976 | |||
1974 | sonypi.*= [HW] Sony Programmable I/O Control Device driver | 1977 | sonypi.*= [HW] Sony Programmable I/O Control Device driver |
1975 | See Documentation/sonypi.txt | 1978 | See Documentation/sonypi.txt |
1976 | 1979 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index 5395a6176f4b..71f5972dc48e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -294,7 +294,8 @@ extern void softlockup_tick(void); | |||
294 | extern void spawn_softlockup_task(void); | 294 | extern void spawn_softlockup_task(void); |
295 | extern void touch_softlockup_watchdog(void); | 295 | extern void touch_softlockup_watchdog(void); |
296 | extern void touch_all_softlockup_watchdogs(void); | 296 | extern void touch_all_softlockup_watchdogs(void); |
297 | extern unsigned long softlockup_thresh; | 297 | extern unsigned int softlockup_panic; |
298 | extern unsigned long softlockup_thresh; | ||
298 | extern unsigned long sysctl_hung_task_check_count; | 299 | extern unsigned long sysctl_hung_task_check_count; |
299 | extern unsigned long sysctl_hung_task_timeout_secs; | 300 | extern unsigned long sysctl_hung_task_timeout_secs; |
300 | extern unsigned long sysctl_hung_task_warnings; | 301 | extern unsigned long sysctl_hung_task_warnings; |
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 01b6522fd92b..78e0ad21cb0c 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
@@ -27,6 +27,21 @@ static DEFINE_PER_CPU(struct task_struct *, watchdog_task); | |||
27 | static int __read_mostly did_panic; | 27 | static int __read_mostly did_panic; |
28 | unsigned long __read_mostly softlockup_thresh = 60; | 28 | unsigned long __read_mostly softlockup_thresh = 60; |
29 | 29 | ||
30 | /* | ||
31 | * Should we panic (and reboot, if panic_timeout= is set) when a | ||
32 | * soft-lockup occurs: | ||
33 | */ | ||
34 | unsigned int __read_mostly softlockup_panic = | ||
35 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; | ||
36 | |||
37 | static int __init softlockup_panic_setup(char *str) | ||
38 | { | ||
39 | softlockup_panic = simple_strtoul(str, NULL, 0); | ||
40 | |||
41 | return 1; | ||
42 | } | ||
43 | __setup("softlockup_panic=", softlockup_panic_setup); | ||
44 | |||
30 | static int | 45 | static int |
31 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) | 46 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) |
32 | { | 47 | { |
@@ -120,6 +135,9 @@ void softlockup_tick(void) | |||
120 | else | 135 | else |
121 | dump_stack(); | 136 | dump_stack(); |
122 | spin_unlock(&print_lock); | 137 | spin_unlock(&print_lock); |
138 | |||
139 | if (softlockup_panic) | ||
140 | panic("softlockup: hung tasks"); | ||
123 | } | 141 | } |
124 | 142 | ||
125 | /* | 143 | /* |
@@ -172,6 +190,9 @@ static void check_hung_task(struct task_struct *t, unsigned long now) | |||
172 | 190 | ||
173 | t->last_switch_timestamp = now; | 191 | t->last_switch_timestamp = now; |
174 | touch_nmi_watchdog(); | 192 | touch_nmi_watchdog(); |
193 | |||
194 | if (softlockup_panic) | ||
195 | panic("softlockup: blocked tasks"); | ||
175 | } | 196 | } |
176 | 197 | ||
177 | /* | 198 | /* |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 29116652dca8..2d3b388c402d 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -729,6 +729,17 @@ static struct ctl_table kern_table[] = { | |||
729 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 729 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
730 | { | 730 | { |
731 | .ctl_name = CTL_UNNUMBERED, | 731 | .ctl_name = CTL_UNNUMBERED, |
732 | .procname = "softlockup_panic", | ||
733 | .data = &softlockup_panic, | ||
734 | .maxlen = sizeof(int), | ||
735 | .mode = 0644, | ||
736 | .proc_handler = &proc_doulongvec_minmax, | ||
737 | .strategy = &sysctl_intvec, | ||
738 | .extra1 = &zero, | ||
739 | .extra2 = &one, | ||
740 | }, | ||
741 | { | ||
742 | .ctl_name = CTL_UNNUMBERED, | ||
732 | .procname = "softlockup_thresh", | 743 | .procname = "softlockup_thresh", |
733 | .data = &softlockup_thresh, | 744 | .data = &softlockup_thresh, |
734 | .maxlen = sizeof(unsigned long), | 745 | .maxlen = sizeof(unsigned long), |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d2099f41aa1e..509ae35a9ef5 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -147,7 +147,7 @@ config DETECT_SOFTLOCKUP | |||
147 | help | 147 | help |
148 | Say Y here to enable the kernel to detect "soft lockups", | 148 | Say Y here to enable the kernel to detect "soft lockups", |
149 | which are bugs that cause the kernel to loop in kernel | 149 | which are bugs that cause the kernel to loop in kernel |
150 | mode for more than 10 seconds, without giving other tasks a | 150 | mode for more than 60 seconds, without giving other tasks a |
151 | chance to run. | 151 | chance to run. |
152 | 152 | ||
153 | When a soft-lockup is detected, the kernel will print the | 153 | When a soft-lockup is detected, the kernel will print the |
@@ -159,6 +159,30 @@ config DETECT_SOFTLOCKUP | |||
159 | can be detected via the NMI-watchdog, on platforms that | 159 | can be detected via the NMI-watchdog, on platforms that |
160 | support it.) | 160 | support it.) |
161 | 161 | ||
162 | config BOOTPARAM_SOFTLOCKUP_PANIC | ||
163 | bool "Panic (Reboot) On Soft Lockups" | ||
164 | depends on DETECT_SOFTLOCKUP | ||
165 | help | ||
166 | Say Y here to enable the kernel to panic on "soft lockups", | ||
167 | which are bugs that cause the kernel to loop in kernel | ||
168 | mode for more than 60 seconds, without giving other tasks a | ||
169 | chance to run. | ||
170 | |||
171 | The panic can be used in combination with panic_timeout, | ||
172 | to cause the system to reboot automatically after a | ||
173 | lockup has been detected. This feature is useful for | ||
174 | high-availability systems that have uptime guarantees and | ||
175 | where a lockup must be resolved ASAP. | ||
176 | |||
177 | Say N if unsure. | ||
178 | |||
179 | config BOOTPARAM_SOFTLOCKUP_PANIC_VALUE | ||
180 | int | ||
181 | depends on DETECT_SOFTLOCKUP | ||
182 | range 0 1 | ||
183 | default 0 if !BOOTPARAM_SOFTLOCKUP_PANIC | ||
184 | default 1 if BOOTPARAM_SOFTLOCKUP_PANIC | ||
185 | |||
162 | config SCHED_DEBUG | 186 | config SCHED_DEBUG |
163 | bool "Collect scheduler debugging info" | 187 | bool "Collect scheduler debugging info" |
164 | depends on DEBUG_KERNEL && PROC_FS | 188 | depends on DEBUG_KERNEL && PROC_FS |