aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--Documentation/sysctl/kernel.txt12
-rw-r--r--include/linux/nmi.h1
-rw-r--r--kernel/sysctl.c9
-rw-r--r--kernel/watchdog.c33
5 files changed, 55 insertions, 5 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6263a2da3e2f..0231f4508abe 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1269,6 +1269,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1269 Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0. 1269 Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
1270 Default: 1024 1270 Default: 1024
1271 1271
1272 hardlockup_all_cpu_backtrace=
1273 [KNL] Should the hard-lockup detector generate
1274 backtraces on all cpus.
1275 Format: <integer>
1276
1272 hashdist= [KNL,NUMA] Large hashes allocated during boot 1277 hashdist= [KNL,NUMA] Large hashes allocated during boot
1273 are distributed across NUMA nodes. Defaults on 1278 are distributed across NUMA nodes. Defaults on
1274 for 64-bit NUMA, off otherwise. 1279 for 64-bit NUMA, off otherwise.
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 6fccb69c03e7..af70d1541d3a 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -33,6 +33,7 @@ show up in /proc/sys/kernel:
33- domainname 33- domainname
34- hostname 34- hostname
35- hotplug 35- hotplug
36- hardlockup_all_cpu_backtrace
36- hung_task_panic 37- hung_task_panic
37- hung_task_check_count 38- hung_task_check_count
38- hung_task_timeout_secs 39- hung_task_timeout_secs
@@ -293,6 +294,17 @@ domain names are in general different. For a detailed discussion
293see the hostname(1) man page. 294see the hostname(1) man page.
294 295
295============================================================== 296==============================================================
297hardlockup_all_cpu_backtrace:
298
299This value controls the hard lockup detector behavior when a hard
300lockup condition is detected as to whether or not to gather further
301debug information. If enabled, arch-specific all-CPU stack dumping
302will be initiated.
303
3040: do nothing. This is the default behavior.
305
3061: on detection capture more debug information.
307==============================================================
296 308
297hotplug: 309hotplug:
298 310
diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index 78488e099ce7..7ec5b86735f3 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -73,6 +73,7 @@ extern int watchdog_user_enabled;
73extern int watchdog_thresh; 73extern int watchdog_thresh;
74extern unsigned long *watchdog_cpumask_bits; 74extern unsigned long *watchdog_cpumask_bits;
75extern int sysctl_softlockup_all_cpu_backtrace; 75extern int sysctl_softlockup_all_cpu_backtrace;
76extern int sysctl_hardlockup_all_cpu_backtrace;
76struct ctl_table; 77struct ctl_table;
77extern int proc_watchdog(struct ctl_table *, int , 78extern int proc_watchdog(struct ctl_table *, int ,
78 void __user *, size_t *, loff_t *); 79 void __user *, size_t *, loff_t *);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 96c856b04081..1a5faa3e1521 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -898,6 +898,15 @@ static struct ctl_table kern_table[] = {
898 .extra1 = &zero, 898 .extra1 = &zero,
899 .extra2 = &one, 899 .extra2 = &one,
900 }, 900 },
901 {
902 .procname = "hardlockup_all_cpu_backtrace",
903 .data = &sysctl_hardlockup_all_cpu_backtrace,
904 .maxlen = sizeof(int),
905 .mode = 0644,
906 .proc_handler = proc_dointvec_minmax,
907 .extra1 = &zero,
908 .extra2 = &one,
909 },
901#endif /* CONFIG_SMP */ 910#endif /* CONFIG_SMP */
902#endif 911#endif
903#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) 912#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 452e4ed507e5..f6b32b8cbffe 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -57,8 +57,10 @@ int __read_mostly watchdog_thresh = 10;
57 57
58#ifdef CONFIG_SMP 58#ifdef CONFIG_SMP
59int __read_mostly sysctl_softlockup_all_cpu_backtrace; 59int __read_mostly sysctl_softlockup_all_cpu_backtrace;
60int __read_mostly sysctl_hardlockup_all_cpu_backtrace;
60#else 61#else
61#define sysctl_softlockup_all_cpu_backtrace 0 62#define sysctl_softlockup_all_cpu_backtrace 0
63#define sysctl_hardlockup_all_cpu_backtrace 0
62#endif 64#endif
63static struct cpumask watchdog_cpumask __read_mostly; 65static struct cpumask watchdog_cpumask __read_mostly;
64unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask); 66unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask);
@@ -112,6 +114,7 @@ static unsigned long soft_lockup_nmi_warn;
112#ifdef CONFIG_HARDLOCKUP_DETECTOR 114#ifdef CONFIG_HARDLOCKUP_DETECTOR
113static int hardlockup_panic = 115static int hardlockup_panic =
114 CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; 116 CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE;
117static unsigned long hardlockup_allcpu_dumped;
115/* 118/*
116 * We may not want to enable hard lockup detection by default in all cases, 119 * We may not want to enable hard lockup detection by default in all cases,
117 * for example when running the kernel as a guest on a hypervisor. In these 120 * for example when running the kernel as a guest on a hypervisor. In these
@@ -173,6 +176,13 @@ static int __init softlockup_all_cpu_backtrace_setup(char *str)
173 return 1; 176 return 1;
174} 177}
175__setup("softlockup_all_cpu_backtrace=", softlockup_all_cpu_backtrace_setup); 178__setup("softlockup_all_cpu_backtrace=", softlockup_all_cpu_backtrace_setup);
179static int __init hardlockup_all_cpu_backtrace_setup(char *str)
180{
181 sysctl_hardlockup_all_cpu_backtrace =
182 !!simple_strtol(str, NULL, 0);
183 return 1;
184}
185__setup("hardlockup_all_cpu_backtrace=", hardlockup_all_cpu_backtrace_setup);
176#endif 186#endif
177 187
178/* 188/*
@@ -318,17 +328,30 @@ static void watchdog_overflow_callback(struct perf_event *event,
318 */ 328 */
319 if (is_hardlockup()) { 329 if (is_hardlockup()) {
320 int this_cpu = smp_processor_id(); 330 int this_cpu = smp_processor_id();
331 struct pt_regs *regs = get_irq_regs();
321 332
322 /* only print hardlockups once */ 333 /* only print hardlockups once */
323 if (__this_cpu_read(hard_watchdog_warn) == true) 334 if (__this_cpu_read(hard_watchdog_warn) == true)
324 return; 335 return;
325 336
326 if (hardlockup_panic) 337 pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu);
327 panic("Watchdog detected hard LOCKUP on cpu %d", 338 print_modules();
328 this_cpu); 339 print_irqtrace_events(current);
340 if (regs)
341 show_regs(regs);
329 else 342 else
330 WARN(1, "Watchdog detected hard LOCKUP on cpu %d", 343 dump_stack();
331 this_cpu); 344
345 /*
346 * Perform all-CPU dump only once to avoid multiple hardlockups
347 * generating interleaving traces
348 */
349 if (sysctl_hardlockup_all_cpu_backtrace &&
350 !test_and_set_bit(0, &hardlockup_allcpu_dumped))
351 trigger_allbutself_cpu_backtrace();
352
353 if (hardlockup_panic)
354 panic("Hard LOCKUP");
332 355
333 __this_cpu_write(hard_watchdog_warn, true); 356 __this_cpu_write(hard_watchdog_warn, true);
334 return; 357 return;