aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/watchdog.c
diff options
context:
space:
mode:
authorUlrich Obergfell <uobergfe@redhat.com>2015-04-14 18:44:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 19:48:59 -0400
commit195daf665a6299de98a4da3843fed2dd9de19d3a (patch)
tree3f7b786d4dfafa6a4d4090e529f7858f60112c75 /kernel/watchdog.c
parentbcfba4f4bf3c9c7c72b459d52a9e826dfd72855e (diff)
watchdog: enable the new user interface of the watchdog mechanism
With the current user interface of the watchdog mechanism it is only possible to disable or enable both lockup detectors at the same time. This series introduces new kernel parameters and changes the semantics of some existing kernel parameters, so that the hard lockup detector and the soft lockup detector can be disabled or enabled individually. With this series applied, the user interface is as follows. - parameters in /proc/sys/kernel . soft_watchdog This is a new parameter to control and examine the run state of the soft lockup detector. . nmi_watchdog The semantics of this parameter have changed. It can now be used to control and examine the run state of the hard lockup detector. . watchdog This parameter is still available to control the run state of both lockup detectors at the same time. If this parameter is examined, it shows the logical OR of soft_watchdog and nmi_watchdog. . watchdog_thresh The semantics of this parameter are not affected by the patch. - kernel command line parameters . nosoftlockup The semantics of this parameter have changed. It can now be used to disable the soft lockup detector at boot time. . nmi_watchdog=0 or nmi_watchdog=1 Disable or enable the hard lockup detector at boot time. The patch introduces '=1' as a new option. . nowatchdog The semantics of this parameter are not affected by the patch. It is still available to disable both lockup detectors at boot time. Also, remove the proc_dowatchdog() function which is no longer needed. [dzickus@redhat.com: wrote changelog] [dzickus@redhat.com: update documentation for kernel params and sysctl] Signed-off-by: Ulrich Obergfell <uobergfe@redhat.com> Signed-off-by: Don Zickus <dzickus@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/watchdog.c')
-rw-r--r--kernel/watchdog.c81
1 files changed, 16 insertions, 65 deletions
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index fd2b6dc14486..63d702885686 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -110,15 +110,9 @@ static int __init hardlockup_panic_setup(char *str)
110 else if (!strncmp(str, "nopanic", 7)) 110 else if (!strncmp(str, "nopanic", 7))
111 hardlockup_panic = 0; 111 hardlockup_panic = 0;
112 else if (!strncmp(str, "0", 1)) 112 else if (!strncmp(str, "0", 1))
113 watchdog_user_enabled = 0; 113 watchdog_enabled &= ~NMI_WATCHDOG_ENABLED;
114 else if (!strncmp(str, "1", 1) || !strncmp(str, "2", 1)) { 114 else if (!strncmp(str, "1", 1))
115 /* 115 watchdog_enabled |= NMI_WATCHDOG_ENABLED;
116 * Setting 'nmi_watchdog=1' or 'nmi_watchdog=2' (legacy option)
117 * has the same effect.
118 */
119 watchdog_user_enabled = 1;
120 watchdog_enable_hardlockup_detector(true);
121 }
122 return 1; 116 return 1;
123} 117}
124__setup("nmi_watchdog=", hardlockup_panic_setup); 118__setup("nmi_watchdog=", hardlockup_panic_setup);
@@ -137,19 +131,18 @@ __setup("softlockup_panic=", softlockup_panic_setup);
137 131
138static int __init nowatchdog_setup(char *str) 132static int __init nowatchdog_setup(char *str)
139{ 133{
140 watchdog_user_enabled = 0; 134 watchdog_enabled = 0;
141 return 1; 135 return 1;
142} 136}
143__setup("nowatchdog", nowatchdog_setup); 137__setup("nowatchdog", nowatchdog_setup);
144 138
145/* deprecated */
146static int __init nosoftlockup_setup(char *str) 139static int __init nosoftlockup_setup(char *str)
147{ 140{
148 watchdog_user_enabled = 0; 141 watchdog_enabled &= ~SOFT_WATCHDOG_ENABLED;
149 return 1; 142 return 1;
150} 143}
151__setup("nosoftlockup", nosoftlockup_setup); 144__setup("nosoftlockup", nosoftlockup_setup);
152/* */ 145
153#ifdef CONFIG_SMP 146#ifdef CONFIG_SMP
154static int __init softlockup_all_cpu_backtrace_setup(char *str) 147static int __init softlockup_all_cpu_backtrace_setup(char *str)
155{ 148{
@@ -264,10 +257,11 @@ static int is_softlockup(unsigned long touch_ts)
264{ 257{
265 unsigned long now = get_timestamp(); 258 unsigned long now = get_timestamp();
266 259
267 /* Warn about unreasonable delays: */ 260 if (watchdog_enabled & SOFT_WATCHDOG_ENABLED) {
268 if (time_after(now, touch_ts + get_softlockup_thresh())) 261 /* Warn about unreasonable delays. */
269 return now - touch_ts; 262 if (time_after(now, touch_ts + get_softlockup_thresh()))
270 263 return now - touch_ts;
264 }
271 return 0; 265 return 0;
272} 266}
273 267
@@ -532,6 +526,10 @@ static int watchdog_nmi_enable(unsigned int cpu)
532 struct perf_event_attr *wd_attr; 526 struct perf_event_attr *wd_attr;
533 struct perf_event *event = per_cpu(watchdog_ev, cpu); 527 struct perf_event *event = per_cpu(watchdog_ev, cpu);
534 528
529 /* nothing to do if the hard lockup detector is disabled */
530 if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
531 goto out;
532
535 /* 533 /*
536 * Some kernels need to default hard lockup detection to 534 * Some kernels need to default hard lockup detection to
537 * 'disabled', for example a guest on a hypervisor. 535 * 'disabled', for example a guest on a hypervisor.
@@ -856,59 +854,12 @@ out:
856 mutex_unlock(&watchdog_proc_mutex); 854 mutex_unlock(&watchdog_proc_mutex);
857 return err; 855 return err;
858} 856}
859
860/*
861 * proc handler for /proc/sys/kernel/nmi_watchdog,watchdog_thresh
862 */
863
864int proc_dowatchdog(struct ctl_table *table, int write,
865 void __user *buffer, size_t *lenp, loff_t *ppos)
866{
867 int err, old_thresh, old_enabled;
868 bool old_hardlockup;
869
870 mutex_lock(&watchdog_proc_mutex);
871 old_thresh = ACCESS_ONCE(watchdog_thresh);
872 old_enabled = ACCESS_ONCE(watchdog_user_enabled);
873 old_hardlockup = watchdog_hardlockup_detector_is_enabled();
874
875 err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
876 if (err || !write)
877 goto out;
878
879 set_sample_period();
880 /*
881 * Watchdog threads shouldn't be enabled if they are
882 * disabled. The 'watchdog_running' variable check in
883 * watchdog_*_all_cpus() function takes care of this.
884 */
885 if (watchdog_user_enabled && watchdog_thresh) {
886 /*
887 * Prevent a change in watchdog_thresh accidentally overriding
888 * the enablement of the hardlockup detector.
889 */
890 if (watchdog_user_enabled != old_enabled)
891 watchdog_enable_hardlockup_detector(true);
892 err = watchdog_enable_all_cpus(old_thresh != watchdog_thresh);
893 } else
894 watchdog_disable_all_cpus();
895
896 /* Restore old values on failure */
897 if (err) {
898 watchdog_thresh = old_thresh;
899 watchdog_user_enabled = old_enabled;
900 watchdog_enable_hardlockup_detector(old_hardlockup);
901 }
902out:
903 mutex_unlock(&watchdog_proc_mutex);
904 return err;
905}
906#endif /* CONFIG_SYSCTL */ 857#endif /* CONFIG_SYSCTL */
907 858
908void __init lockup_detector_init(void) 859void __init lockup_detector_init(void)
909{ 860{
910 set_sample_period(); 861 set_sample_period();
911 862
912 if (watchdog_user_enabled) 863 if (watchdog_enabled)
913 watchdog_enable_all_cpus(false); 864 watchdog_enable_all_cpus(false);
914} 865}