aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2015-01-13 13:49:06 +0000
committerDaniel Thompson <daniel.thompson@linaro.org>2015-01-27 11:58:32 +0000
commit2a3398f218ada6feaf3f5714c374168a59694eae (patch)
tree5804f3ff1a382621592635883fd84e9ecad822ee
parentb304ea3e164714e1540b7bc69b3205a12d953e79 (diff)
downloadlinux-2a3398f218ada6feaf3f5714c374168a59694eae.tar.gz
ARM: Minimal support for the hard lockup dectector
Currently there is no support for the hard lockup detector (a.k.a. the NMI watchdog) for ARM. This patch provides the absolute bare minimum needed to allow the watchdog to operate and does not tackle a few complications. In particular boot ordering issues prevent the watchdog from starting without assistance from userspace (the watchdog is initialized before the PMU). Likewise there is no logic to automatically disable the watchdog on systems with no support for FIQ (the watchdog is safe to run from IRQ but it becomes ineffective). Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
-rw-r--r--arch/arm/Kconfig6
-rw-r--r--arch/arm/include/asm/nmi.h3
-rw-r--r--arch/arm/kernel/perf_event_cpu.c33
3 files changed, 42 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 91d62731b52d..e4315a7941bf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -62,6 +62,7 @@ config ARM
select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_PERF_EVENTS
+ select HAVE_PERF_EVENTS_NMI if MIGHT_HAVE_FIQ
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE)
@@ -120,6 +121,10 @@ config ARM_DMA_IOMMU_ALIGNMENT
endif
+config MIGHT_HAVE_FIQ
+ bool
+ default y if FIQ
+
config MIGHT_HAVE_PCI
bool
@@ -317,6 +322,7 @@ config ARCH_MULTIPLATFORM
select CLKSRC_OF
select COMMON_CLK
select GENERIC_CLOCKEVENTS
+ select MIGHT_HAVE_FIQ
select MIGHT_HAVE_PCI
select MULTI_IRQ_HANDLER
select SPARSE_IRQ
diff --git a/arch/arm/include/asm/nmi.h b/arch/arm/include/asm/nmi.h
new file mode 100644
index 000000000000..90069c2850b5
--- /dev/null
+++ b/arch/arm/include/asm/nmi.h
@@ -0,0 +1,3 @@
+/*
+ * This (empty) file exists to allow it to be included by linux/nmi.h
+ */
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index dd9acc95ebc0..b30a2645c2f1 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -27,6 +27,7 @@
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/irqdesc.h>
+#include <linux/nmi.h>
#include <asm/cputype.h>
#include <asm/irq_regs.h>
@@ -59,6 +60,38 @@ int perf_num_counters(void)
}
EXPORT_SYMBOL_GPL(perf_num_counters);
+#ifdef CONFIG_HAVE_PERF_EVENTS_NMI
+/*
+ * Used by the hard lockup detector to determine how many PMU cycles
+ * would elapse in watchdog_thresh seconds.
+ */
+u64 hw_nmi_get_sample_period(int watchdog_thresh)
+{
+ /*
+ * It is very difficult to determine the CPU frequency and, even
+ * if we did, there's nothing to say it won't change
+ * dramatically in the future.
+ *
+ * Therefore this code acts as though we have a 2GHz clock.
+ * watchdog_thresh has a significant margin for error built into
+ * it by the wadtchdog code, so this should keep the watchdog
+ * working correctly even on chips that approach double this speed.
+ *
+ * The downside of taking such a large value is that on older
+ * parts it will take a long time for the hard lockup detector
+ * to fire.
+ */
+ return 2000000000ull * watchdog_thresh;
+}
+#endif
+
+#ifdef CONFIG_OPROFILE_NMI_TIMER
+int op_nmi_timer_init(struct oprofile_operations *ops)
+{
+ return -ENODEV;
+}
+#endif
+
/* Include the PMU-specific implementations. */
#include "perf_event_xscale.c"
#include "perf_event_v6.c"