|
@@ -110,15 +110,9 @@ static int __init hardlockup_panic_setup(char *str)
|
|
|
else if (!strncmp(str, "nopanic", 7))
|
|
|
hardlockup_panic = 0;
|
|
|
else if (!strncmp(str, "0", 1))
|
|
|
- watchdog_user_enabled = 0;
|
|
|
- else if (!strncmp(str, "1", 1) || !strncmp(str, "2", 1)) {
|
|
|
- /*
|
|
|
- * Setting 'nmi_watchdog=1' or 'nmi_watchdog=2' (legacy option)
|
|
|
- * has the same effect.
|
|
|
- */
|
|
|
- watchdog_user_enabled = 1;
|
|
|
- watchdog_enable_hardlockup_detector(true);
|
|
|
- }
|
|
|
+ watchdog_enabled &= ~NMI_WATCHDOG_ENABLED;
|
|
|
+ else if (!strncmp(str, "1", 1))
|
|
|
+ watchdog_enabled |= NMI_WATCHDOG_ENABLED;
|
|
|
return 1;
|
|
|
}
|
|
|
__setup("nmi_watchdog=", hardlockup_panic_setup);
|
|
@@ -137,19 +131,18 @@ __setup("softlockup_panic=", softlockup_panic_setup);
|
|
|
|
|
|
static int __init nowatchdog_setup(char *str)
|
|
|
{
|
|
|
- watchdog_user_enabled = 0;
|
|
|
+ watchdog_enabled = 0;
|
|
|
return 1;
|
|
|
}
|
|
|
__setup("nowatchdog", nowatchdog_setup);
|
|
|
|
|
|
-/* deprecated */
|
|
|
static int __init nosoftlockup_setup(char *str)
|
|
|
{
|
|
|
- watchdog_user_enabled = 0;
|
|
|
+ watchdog_enabled &= ~SOFT_WATCHDOG_ENABLED;
|
|
|
return 1;
|
|
|
}
|
|
|
__setup("nosoftlockup", nosoftlockup_setup);
|
|
|
-/* */
|
|
|
+
|
|
|
#ifdef CONFIG_SMP
|
|
|
static int __init softlockup_all_cpu_backtrace_setup(char *str)
|
|
|
{
|
|
@@ -264,10 +257,11 @@ static int is_softlockup(unsigned long touch_ts)
|
|
|
{
|
|
|
unsigned long now = get_timestamp();
|
|
|
|
|
|
- /* Warn about unreasonable delays: */
|
|
|
- if (time_after(now, touch_ts + get_softlockup_thresh()))
|
|
|
- return now - touch_ts;
|
|
|
-
|
|
|
+ if (watchdog_enabled & SOFT_WATCHDOG_ENABLED) {
|
|
|
+ /* Warn about unreasonable delays. */
|
|
|
+ if (time_after(now, touch_ts + get_softlockup_thresh()))
|
|
|
+ return now - touch_ts;
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -532,6 +526,10 @@ static int watchdog_nmi_enable(unsigned int cpu)
|
|
|
struct perf_event_attr *wd_attr;
|
|
|
struct perf_event *event = per_cpu(watchdog_ev, cpu);
|
|
|
|
|
|
+ /* nothing to do if the hard lockup detector is disabled */
|
|
|
+ if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
|
|
|
+ goto out;
|
|
|
+
|
|
|
/*
|
|
|
* Some kernels need to default hard lockup detection to
|
|
|
* 'disabled', for example a guest on a hypervisor.
|
|
@@ -856,59 +854,12 @@ out:
|
|
|
mutex_unlock(&watchdog_proc_mutex);
|
|
|
return err;
|
|
|
}
|
|
|
-
|
|
|
-/*
|
|
|
- * proc handler for /proc/sys/kernel/nmi_watchdog,watchdog_thresh
|
|
|
- */
|
|
|
-
|
|
|
-int proc_dowatchdog(struct ctl_table *table, int write,
|
|
|
- void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
|
-{
|
|
|
- int err, old_thresh, old_enabled;
|
|
|
- bool old_hardlockup;
|
|
|
-
|
|
|
- mutex_lock(&watchdog_proc_mutex);
|
|
|
- old_thresh = ACCESS_ONCE(watchdog_thresh);
|
|
|
- old_enabled = ACCESS_ONCE(watchdog_user_enabled);
|
|
|
- old_hardlockup = watchdog_hardlockup_detector_is_enabled();
|
|
|
-
|
|
|
- err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
|
|
|
- if (err || !write)
|
|
|
- goto out;
|
|
|
-
|
|
|
- set_sample_period();
|
|
|
- /*
|
|
|
- * Watchdog threads shouldn't be enabled if they are
|
|
|
- * disabled. The 'watchdog_running' variable check in
|
|
|
- * watchdog_*_all_cpus() function takes care of this.
|
|
|
- */
|
|
|
- if (watchdog_user_enabled && watchdog_thresh) {
|
|
|
- /*
|
|
|
- * Prevent a change in watchdog_thresh accidentally overriding
|
|
|
- * the enablement of the hardlockup detector.
|
|
|
- */
|
|
|
- if (watchdog_user_enabled != old_enabled)
|
|
|
- watchdog_enable_hardlockup_detector(true);
|
|
|
- err = watchdog_enable_all_cpus(old_thresh != watchdog_thresh);
|
|
|
- } else
|
|
|
- watchdog_disable_all_cpus();
|
|
|
-
|
|
|
- /* Restore old values on failure */
|
|
|
- if (err) {
|
|
|
- watchdog_thresh = old_thresh;
|
|
|
- watchdog_user_enabled = old_enabled;
|
|
|
- watchdog_enable_hardlockup_detector(old_hardlockup);
|
|
|
- }
|
|
|
-out:
|
|
|
- mutex_unlock(&watchdog_proc_mutex);
|
|
|
- return err;
|
|
|
-}
|
|
|
#endif /* CONFIG_SYSCTL */
|
|
|
|
|
|
void __init lockup_detector_init(void)
|
|
|
{
|
|
|
set_sample_period();
|
|
|
|
|
|
- if (watchdog_user_enabled)
|
|
|
+ if (watchdog_enabled)
|
|
|
watchdog_enable_all_cpus(false);
|
|
|
}
|