From 2a3398f218ada6feaf3f5714c374168a59694eae Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Tue, 13 Jan 2015 13:49:06 +0000 Subject: 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 --- arch/arm/Kconfig | 6 ++++++ arch/arm/include/asm/nmi.h | 3 +++ arch/arm/kernel/perf_event_cpu.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 arch/arm/include/asm/nmi.h 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 #include #include +#include #include #include @@ -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" -- cgit v1.2.3