When there are more than one implementation of the NMI watchdog, there may
be situations in which switching from one to another is needed (e.g., if
the time-stamp counter becomes unstable, the HPET-based NMI watchdog can
no longer be used.

The perf-based implementation of the hardlockup detector makes use of
various per-CPU variables which are accessed via this_cpu operations.
Hence, each CPU needs to enable its own NMI watchdog if using the perf
implementation.

Add functionality to switch from one NMI watchdog to another and do it
from each allowed CPU.

Cc: "H. Peter Anvin" <[email protected]>
Cc: Ashok Raj <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: Don Zickus <[email protected]>
Cc: Nicholas Piggin <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Alexei Starovoitov <[email protected]>
Cc: Babu Moger <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Mathieu Desnoyers <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Philippe Ombredanne <[email protected]>
Cc: Colin Ian King <[email protected]>
Cc: Byungchul Park <[email protected]>
Cc: "Paul E. McKenney" <[email protected]>
Cc: "Luis R. Rodriguez" <[email protected]>
Cc: Waiman Long <[email protected]>
Cc: Josh Poimboeuf <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Davidlohr Bueso <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Kai-Heng Feng <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Suravee Suthikulpanit <[email protected]>
Cc: "Ravi V. Shankar" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Ricardo Neri <[email protected]>
---
 include/linux/nmi.h |  2 ++
 kernel/watchdog.c   | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index e5f1a86e20b7..6d828334348b 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -83,9 +83,11 @@ static inline void reset_hung_task_detector(void) { }
 
 #if defined(CONFIG_HARDLOCKUP_DETECTOR)
 extern void hardlockup_detector_disable(void);
+extern void hardlockup_start_all(void);
 extern unsigned int hardlockup_panic;
 #else
 static inline void hardlockup_detector_disable(void) {}
+static inline void hardlockup_start_all(void) {}
 #endif
 
 #if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR)
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 7f9e7b9306fe..be589001200a 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -566,6 +566,21 @@ int lockup_detector_offline_cpu(unsigned int cpu)
        return 0;
 }
 
+static int hardlockup_start_fn(void *data)
+{
+       watchdog_nmi_enable(smp_processor_id());
+       return 0;
+}
+
+void hardlockup_start_all(void)
+{
+       int cpu;
+
+       cpumask_copy(&watchdog_allowed_mask, &watchdog_cpumask);
+       for_each_cpu(cpu, &watchdog_allowed_mask)
+               smp_call_on_cpu(cpu, hardlockup_start_fn, NULL, false);
+}
+
 static void lockup_detector_reconfigure(void)
 {
        cpus_read_lock();
-- 
2.17.1

Reply via email to