diff options
-rw-r--r-- | Documentation/sysctl/kernel.txt | 8 | ||||
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | kernel/softlockup.c | 7 | ||||
-rw-r--r-- | kernel/sysctl.c | 33 |
4 files changed, 40 insertions, 9 deletions
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 111fd28727ec..8984a5396271 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -320,6 +320,14 @@ kernel. This value defaults to SHMMAX. | |||
320 | 320 | ||
321 | ============================================================== | 321 | ============================================================== |
322 | 322 | ||
323 | softlockup_thresh: | ||
324 | |||
325 | This value can be used to lower the softlockup tolerance | ||
326 | threshold. The default threshold is 10s. If a cpu is locked up | ||
327 | for 10s, the kernel complains. Valid values are 1-60s. | ||
328 | |||
329 | ============================================================== | ||
330 | |||
323 | tainted: | 331 | tainted: |
324 | 332 | ||
325 | Non-zero if the kernel has been tainted. Numeric values, which | 333 | Non-zero if the kernel has been tainted. Numeric values, which |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 59738efff8ad..e643357eda05 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -261,6 +261,7 @@ extern void softlockup_tick(void); | |||
261 | extern void spawn_softlockup_task(void); | 261 | extern void spawn_softlockup_task(void); |
262 | extern void touch_softlockup_watchdog(void); | 262 | extern void touch_softlockup_watchdog(void); |
263 | extern void touch_all_softlockup_watchdogs(void); | 263 | extern void touch_all_softlockup_watchdogs(void); |
264 | extern int softlockup_thresh; | ||
264 | #else | 265 | #else |
265 | static inline void softlockup_tick(void) | 266 | static inline void softlockup_tick(void) |
266 | { | 267 | { |
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 72c2561ff5f8..edeeef3a6a32 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
@@ -24,6 +24,7 @@ static DEFINE_PER_CPU(unsigned long, print_timestamp); | |||
24 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); | 24 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); |
25 | 25 | ||
26 | static int did_panic; | 26 | static int did_panic; |
27 | int softlockup_thresh = 10; | ||
27 | 28 | ||
28 | static int | 29 | static int |
29 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) | 30 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) |
@@ -104,13 +105,15 @@ void softlockup_tick(void) | |||
104 | wake_up_process(per_cpu(watchdog_task, this_cpu)); | 105 | wake_up_process(per_cpu(watchdog_task, this_cpu)); |
105 | 106 | ||
106 | /* Warn about unreasonable 10+ seconds delays: */ | 107 | /* Warn about unreasonable 10+ seconds delays: */ |
107 | if (now <= (touch_timestamp + 10)) | 108 | if (now <= (touch_timestamp + softlockup_thresh)) |
108 | return; | 109 | return; |
109 | 110 | ||
110 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; | 111 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; |
111 | 112 | ||
112 | spin_lock(&print_lock); | 113 | spin_lock(&print_lock); |
113 | printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n", this_cpu); | 114 | printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n", |
115 | this_cpu, now - touch_timestamp, | ||
116 | current->comm, current->pid); | ||
114 | if (regs) | 117 | if (regs) |
115 | show_regs(regs); | 118 | show_regs(regs); |
116 | else | 119 | else |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 5e63de0f9ee2..dde3d53e8adc 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -80,6 +80,19 @@ extern int maps_protect; | |||
80 | extern int sysctl_stat_interval; | 80 | extern int sysctl_stat_interval; |
81 | extern int audit_argv_kb; | 81 | extern int audit_argv_kb; |
82 | 82 | ||
83 | /* Constants used for minimum and maximum */ | ||
84 | #ifdef CONFIG_DETECT_SOFTLOCKUP | ||
85 | static int one = 1; | ||
86 | static int sixty = 60; | ||
87 | #endif | ||
88 | |||
89 | #ifdef CONFIG_MMU | ||
90 | static int two = 2; | ||
91 | #endif | ||
92 | |||
93 | static int zero; | ||
94 | static int one_hundred = 100; | ||
95 | |||
83 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ | 96 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ |
84 | static int maxolduid = 65535; | 97 | static int maxolduid = 65535; |
85 | static int minolduid; | 98 | static int minolduid; |
@@ -711,6 +724,19 @@ static ctl_table kern_table[] = { | |||
711 | .proc_handler = &proc_dointvec, | 724 | .proc_handler = &proc_dointvec, |
712 | }, | 725 | }, |
713 | #endif | 726 | #endif |
727 | #ifdef CONFIG_DETECT_SOFTLOCKUP | ||
728 | { | ||
729 | .ctl_name = CTL_UNNUMBERED, | ||
730 | .procname = "softlockup_thresh", | ||
731 | .data = &softlockup_thresh, | ||
732 | .maxlen = sizeof(int), | ||
733 | .mode = 0644, | ||
734 | .proc_handler = &proc_dointvec_minmax, | ||
735 | .strategy = &sysctl_intvec, | ||
736 | .extra1 = &one, | ||
737 | .extra2 = &sixty, | ||
738 | }, | ||
739 | #endif | ||
714 | #ifdef CONFIG_COMPAT | 740 | #ifdef CONFIG_COMPAT |
715 | { | 741 | { |
716 | .ctl_name = KERN_COMPAT_LOG, | 742 | .ctl_name = KERN_COMPAT_LOG, |
@@ -757,13 +783,6 @@ static ctl_table kern_table[] = { | |||
757 | { .ctl_name = 0 } | 783 | { .ctl_name = 0 } |
758 | }; | 784 | }; |
759 | 785 | ||
760 | /* Constants for minimum and maximum testing in vm_table. | ||
761 | We use these as one-element integer vectors. */ | ||
762 | static int zero; | ||
763 | static int two = 2; | ||
764 | static int one_hundred = 100; | ||
765 | |||
766 | |||
767 | static ctl_table vm_table[] = { | 786 | static ctl_table vm_table[] = { |
768 | { | 787 | { |
769 | .ctl_name = VM_OVERCOMMIT_MEMORY, | 788 | .ctl_name = VM_OVERCOMMIT_MEMORY, |