Improve watchdog config for arch watchdogs
Subsystems (6)
Nicholas Piggin
reviewerv4 cover Improve watchdog config for arch watchdogs
This is the latest series to make the hardlockup watchdog more easily replaceable by arch code. The last patch provides some justification for why we want to do this (existing sparc watchdog is another that could benefit).
Since last time, we tidied up the Kconfig approach so it was not so jumbled -- Thanks Don and Babu for help and suggestions there.
Since last posting the powerpc patch, I re-added the soft-NMI watchdog, but have it using the emergency stack so we can always avoid the process stacks when perf interrupts are soft-masked.
I'm not sure of the best strategy to merge this. The powerpc watchdog is too much to carry anywhere but powerpc tree now, and watchdog patches seem to go via Andrew...
Thanks,
Nick
Nicholas Piggin (5):
watchdog: remove unused declaration
watchdog: introduce arch_touch_nmi_watchdog()
watchdog: split up config options
watchdog: provide watchdog_reconfigure() for arch watchdogs powerpc/64s: implement arch-specific hardlockup watchdog
arch/Kconfig | 23 ++ arch/blackfin/include/asm/nmi.h | 2 + arch/blackfin/kernel/nmi.c | 2 +- arch/mn10300/include/asm/nmi.h | 2 + arch/mn10300/kernel/mn10300-watchdog-low.S | 8 +- arch/mn10300/kernel/mn10300-watchdog.c | 2 +- arch/powerpc/Kconfig | 6 +- arch/powerpc/include/asm/nmi.h | 11 + arch/powerpc/include/asm/smp.h | 2 + arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/exceptions-64s.S | 30 ++- arch/powerpc/kernel/kvm.c | 7 + arch/powerpc/kernel/setup_64.c | 19 -- arch/powerpc/kernel/smp.c | 20 +- arch/powerpc/kernel/watchdog.c | 388 +++++++++++++++++++++++++++++ arch/sparc/include/asm/nmi.h | 1 + arch/sparc/kernel/nmi.c | 6 +- arch/x86/Kconfig | 1 + arch/x86/kernel/apic/hw_nmi.c | 2 +- include/linux/nmi.h | 57 +++-- kernel/Makefile | 2 +- kernel/sysctl.c | 31 ++- kernel/watchdog.c | 268 +++++++++++++------- kernel/watchdog_hld.c | 37 +-- lib/Kconfig.debug | 45 ++-- 25 files changed, 763 insertions(+), 210 deletions(-) create mode 100644 arch/powerpc/kernel/watchdog.c
Signature · 1 line
2.11.0
Nicholas Piggin
reviewerPATCH v4 1/5 watchdog: remove unused declaration
--- include/linux/nmi.h | 3 --- 1 file changed, 3 deletions(-)
include/linux/nmi.h +0 -3
@@ -12,9 +12,6 @@ extern void touch_softlockup_watchdog_sched(void);extern void touch_softlockup_watchdog (void );extern void touch_softlockup_watchdog_sync (void );extern void touch_all_softlockup_watchdogs (void ); -extern int proc_dowatchdog_thresh (struct ctl_table *table,int write, -void __user *buffer, -size_t *lenp,loff_t *ppos);extern unsigned int softlockup_panic;extern unsigned int hardlockup_panic;void lockup_detector_init (void );
Signature · 1 line
2.11.0
Nicholas Piggin
reviewerPATCH v4 2/5 watchdog: introduce arch_touch_nmi_watchdog()
In reply to Nicholas PigginFor architectures that define HAVE_NMI_WATCHDOG, instead of having them provide the complete touch_nmi_watchdog() function, just have them provide arch_touch_nmi_watchdog().
This gives the generic code more flexibility in implementing this function, and arch implementations don't miss out on touching the softlockup watchdog or other generic details.
--- arch/blackfin/include/asm/nmi.h | 2 ++ arch/blackfin/kernel/nmi.c | 2 +- arch/mn10300/include/asm/nmi.h | 2 ++ arch/mn10300/kernel/mn10300-watchdog-low.S | 8 ++++---- arch/mn10300/kernel/mn10300-watchdog.c | 2 +- arch/sparc/include/asm/nmi.h | 1 + arch/sparc/kernel/nmi.c | 6 ++---- include/linux/nmi.h | 27 ++++++++++++++++----------- kernel/watchdog_hld.c | 5 ++--- 9 files changed, 31 insertions(+), 24 deletions(-)
arch/blackfin/include/asm/nmi.h +2 -0
@@ -9,4 +9,6 @@#include <linux/nmi.h> +extern void arch_touch_nmi_watchdog (void ); +#endif
arch/blackfin/kernel/nmi.c +1 -1
@@ -190,7 +190,7 @@ static int __init init_nmi_wdt(void) }device_initcall (init_nmi_wdt); -void touch_nmi_watchdog (void ) +void arch_touch_nmi_watchdog (void ) {atomic_set (&nmi_touched[smp_processor_id ()],1 ); }
arch/mn10300/include/asm/nmi.h +2 -0
@@ -11,4 +11,6 @@#ifndef _ASM_NMI_H#define _ASM_NMI_H +extern void arch_touch_nmi_watchdog (void ); +#endif /* _ASM_NMI_H */
arch/mn10300/kernel/mn10300-watchdog-low.S +4 -4
@@ -50,9 +50,9 @@ watchdog_handler: # we can't inline it) # ############################################################################### - .globl touch_nmi_watchdog - .type touch_nmi_watchdog,@function -touch_nmi_watchdog: + .globl arch_touch_nmi_watchdog + .type arch_touch_nmi_watchdog,@function +arch_touch_nmi_watchdog: clr d0 clr d1 mov watchdog_alert_counter, a0
@@ -63,4 +63,4 @@ touch_nmi_watchdog: lne ret [],0 - .size touch_nmi_watchdog,.-touch_nmi_watchdog + .size arch_touch_nmi_watchdog,.-arch_touch_nmi_watchdog
arch/mn10300/kernel/mn10300-watchdog.c +1 -1
@@ -31,7 +31,7 @@ static unsigned int watchdog;static unsigned int watchdog_hz =1 ;unsigned int watchdog_alert_counter[NR_CPUS ]; -EXPORT_SYMBOL (touch_nmi_watchdog); +EXPORT_SYMBOL (arch_touch_nmi_watchdog);/* * the best way to detect whether a CPU has a 'hard lockup' problem
arch/sparc/include/asm/nmi.h +1 -0
@@ -7,6 +7,7 @@ void nmi_adjust_hz(unsigned int new_hz);extern atomic_t nmi_active; +void arch_touch_nmi_watchdog (void );void start_nmi_watchdog (void *unused);void stop_nmi_watchdog (void *unused);
arch/sparc/kernel/nmi.c +2 -4
@@ -51,7 +51,7 @@ static DEFINE_PER_CPU(unsigned int, last_irq_sum); static DEFINE_PER_CPU(long, alert_counter); static DEFINE_PER_CPU(int, nmi_touch); -void touch_nmi_watchdog (void ) +void arch_touch_nmi_watchdog (void ) {if (atomic_read (&nmi_active)) {int cpu;
@@ -61,10 +61,8 @@ void touch_nmi_watchdog(void)per_cpu (nmi_touch, cpu) =1 ; } } - -touch_softlockup_watchdog (); } -EXPORT_SYMBOL (touch_nmi_watchdog); +EXPORT_SYMBOL (arch_touch_nmi_watchdog);static void die_nmi (const char *str,struct pt_regs *regs,int do_panic) {
include/linux/nmi.h +16 -11
@@ -6,6 +6,9 @@#include <linux/sched.h> #include <asm/irq.h> +#if defined(CONFIG_HAVE_NMI_WATCHDOG ) +#include <asm/nmi.h> +#endif #ifdef CONFIG_LOCKUP_DETECTOR extern void touch_softlockup_watchdog_sched (void );
@@ -58,6 +61,18 @@ static inline void reset_hung_task_detector(void)#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT)#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) +#if defined(CONFIG_HARDLOCKUP_DETECTOR ) +extern void hardlockup_detector_disable (void ); +#else +static inline void hardlockup_detector_disable (void ) {} +#endif + +#if defined(CONFIG_HARDLOCKUP_DETECTOR ) || defined(CONFIG_HAVE_NMI_WATCHDOG ) +extern void arch_touch_nmi_watchdog (void ); +#else +static inline void arch_touch_nmi_watchdog (void ) {} +#endif +/** * touch_nmi_watchdog - restart NMI watchdog timeout. *
@@ -65,21 +80,11 @@ static inline void reset_hung_task_detector(void)* may be used to reset the timeout - for code which intentionally * disables interrupts for a long time. This call is stateless. */ -#if defined(CONFIG_HAVE_NMI_WATCHDOG ) || defined(CONFIG_HARDLOCKUP_DETECTOR ) -#include <asm/nmi.h> -extern void touch_nmi_watchdog (void ); -#else static inline void touch_nmi_watchdog (void ) { +arch_touch_nmi_watchdog ();touch_softlockup_watchdog (); } -#endif - -#if defined(CONFIG_HARDLOCKUP_DETECTOR ) -extern void hardlockup_detector_disable (void ); -#else -static inline void hardlockup_detector_disable (void ) {} -#endif /* * Create trigger_all_cpu_backtrace() out of the arch-provided
kernel/watchdog_hld.c +2 -3
@@ -56,7 +56,7 @@ static int __init hardlockup_panic_setup(char *str) }__setup ("nmi_watchdog=" , hardlockup_panic_setup); -void touch_nmi_watchdog (void ) +void arch_touch_nmi_watchdog (void ) {/* * Using __raw here because some code paths have
@@ -66,9 +66,8 @@ void touch_nmi_watchdog(void)* going off. */ raw_cpu_write (watchdog_nmi_touch, true); -touch_softlockup_watchdog (); } -EXPORT_SYMBOL (touch_nmi_watchdog); +EXPORT_SYMBOL (arch_touch_nmi_watchdog);static struct perf_event_attr wd_hw_attr = { .type =PERF_TYPE_HARDWARE ,
Signature · 1 line
2.11.0
Andrew Morton
maintainerRe: [PATCH v4 2/5] watchdog: introduce arch_touch_nmi_watchdog()
Quoted 13 lines · On Fri, 16 Jun 2017 16:57:12 +1000 Nicholas Piggin <[email protected]> wrote:
For architectures that define
HAVE_NMI_WATCHDOG, instead of having them provide the completetouch_nmi_watchdog()function, just have them providearch_touch_nmi_watchdog().This gives the generic code more flexibility in implementing this function, and arch implementations don't miss out on touching the softlockup watchdog or other generic details.
...
arch/blackfin/include/asm/nmi.h line 12
Quoted 4 lines
arch/blackfin/include/asm/nmi.h +1
-0@@ -9,4 +9,6 @@#include <linux/nmi.h> +extern void arch_touch_nmi_watchdog (void );
Do we actually need to add this to the arch header files...
Quoted 21 lines
...
include/linux/nmi.h +5
-0@@ -6,6 +6,9 @@#include <linux/sched.h> #include <asm/irq.h> +#if defined(CONFIG_HAVE_NMI_WATCHDOG ) +#include <asm/nmi.h> +#endif #ifdef CONFIG_LOCKUP_DETECTOR extern void touch_softlockup_watchdog_sched (void );@@ -58,6 +61,18 @@ static inline void reset_hung_task_detector(void)#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT)#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) +#if defined(CONFIG_HARDLOCKUP_DETECTOR ) +extern void hardlockup_detector_disable (void );
include/linux/nmi.h static inline void reset_hung_task_detector(void) · line 75
Quoted 10 lines
include/linux/nmi.h +10
-0+#else +static inline void hardlockup_detector_disable (void ) {} +#endif + +#if defined(CONFIG_HARDLOCKUP_DETECTOR ) || defined(CONFIG_HAVE_NMI_WATCHDOG ) +extern void arch_touch_nmi_watchdog (void ); +#else +static inline void arch_touch_nmi_watchdog (void ) {} +#endif +
given that we have a global declaration here?
Nicholas Piggin
reviewerRe: [PATCH v4 2/5] watchdog: introduce arch_touch_nmi_watchdog()
Quoted 21 lines · On Fri, 16 Jun 2017 11:21:17 -0700 Andrew Morton <[email protected]>…
Quoted 13 lines · On Fri, 16 Jun 2017 16:57:12 +1000 Nicholas Piggin <[email protected]> wrote:
For architectures that define
HAVE_NMI_WATCHDOG, instead of having them provide the completetouch_nmi_watchdog()function, just have them providearch_touch_nmi_watchdog().This gives the generic code more flexibility in implementing this function, and arch implementations don't miss out on touching the softlockup watchdog or other generic details.
...
arch/blackfin/include/asm/nmi.h line 12
Quoted 4 lines
arch/blackfin/include/asm/nmi.h +1
-0@@ -9,4 +9,6 @@#include <linux/nmi.h> +extern void arch_touch_nmi_watchdog (void );Do we actually need to add this to the arch header files...
[snip]
Quoted 8 lines
arch/blackfin/include/asm/nmi.h
Quoted 6 lines
arch/blackfin/include/asm/nmi.h +6
-0+#if defined(CONFIG_HARDLOCKUP_DETECTOR ) || defined(CONFIG_HAVE_NMI_WATCHDOG ) +extern void arch_touch_nmi_watchdog (void ); +#else +static inline void arch_touch_nmi_watchdog (void ) {} +#endif +given that we have a global declaration here?
Probably not. I think it was a holdover from an earlier version where I tried to let the arch declare it (one of the little embedded ones had a comment somewhere saying it would be nice if they could make it inline).
There was some difficulty with it, so yes let's remove these and do that next time.
Thanks,
Nick
Nicholas Piggin
reviewerPATCH v4 3/5 watchdog: split up config options
In reply to Nicholas PigginSplit SOFTLOCKUP_DETECTOR from LOCKUP_DETECTOR, and split HARDLOCKUP_DETECTOR_PERF from HARDLOCKUP_DETECTOR.
LOCKUP_DETECTOR implies the general boot, sysctl, and programming interfaces for the lockup detectors.
An architecture that wants to use a hard lockup detector must define HAVE_HARDLOCKUP_DETECTOR_PERF or HAVE_HARDLOCKUP_DETECTOR_ARCH.
Alternatively an arch can define HAVE_NMI_WATCHDOG, which provides the minimum arch_touch_nmi_watchdog, and it otherwise does its own thing and does not implement the LOCKUP_DETECTOR interfaces.
sparc is unusual in that it has started to implement some of the interfaces, but not fully yet. It should probably be converted to a full HAVE_HARDLOCKUP_DETECTOR_ARCH.
--- arch/Kconfig | 23 ++++ arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/setup_64.c | 2 +- arch/x86/Kconfig | 1 + arch/x86/kernel/apic/hw_nmi.c | 2 +- include/linux/nmi.h | 29 +++-- kernel/Makefile | 2 +- kernel/sysctl.c | 31 +++--- kernel/watchdog.c | 243 +++++++++++++++++++++++++++-------------- kernel/watchdog_hld.c | 32 ------ lib/Kconfig.debug | 45 +++++--- 11 files changed, 252 insertions(+), 159 deletions(-)
arch/Kconfig +23 -0
@@ -288,6 +288,29 @@ config HAVE_PERF_EVENTS_NMI subsystem. Also has support for calculating CPU cycle events to determine how many clock cycles in a given period. + +config HAVE_HARDLOCKUP_DETECTOR_PERF + bool + depends on HAVE_PERF_EVENTS_NMI + help + The arch chooses to use the generic perf-NMI-based hardlockup + detector. Must define HAVE_PERF_EVENTS_NMI. + +config HAVE_NMI_WATCHDOG + bool + help + The arch provides a low level NMI watchdog. It provides + asm/nmi.h, and defines its own arch_touch_nmi_watchdog(). + +config HAVE_HARDLOCKUP_DETECTOR_ARCH + bool + select HAVE_NMI_WATCHDOG + help + The arch chooses to provide its own hardlockup detector, which is + a superset of the HAVE_NMI_WATCHDOG. It also conforms to config + interfaces and parameters provided by hardlockup detector subsystem. + + config HAVE_PERF_REGS bool help
arch/powerpc/Kconfig +1 -0
@@ -202,6 +202,7 @@ config PPC select HAVE_OPTPROBES if PPC64 select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS_NMI if PPC64 + select HAVE_HARDLOCKUP_DETECTOR_PERF if HAVE_PERF_EVENTS_NMI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_RCU_TABLE_FREE if SMP
arch/powerpc/kernel/setup_64.c +1 -1
@@ -727,7 +727,7 @@ struct ppc_pci_io ppc_pci_io;EXPORT_SYMBOL (ppc_pci_io);#endif -#ifdef CONFIG_HARDLOCKUP_DETECTOR +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF u64 hw_nmi_get_sample_period (int watchdog_thresh) {return ppc_proc_freq * watchdog_thresh;
arch/x86/Kconfig +1 -0
@@ -157,6 +157,7 @@ config X86 select HAVE_PCSPKR_PLATFORM select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS_NMI + select HAVE_HARDLOCKUP_DETECTOR_PERF if HAVE_PERF_EVENTS_NMI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API
arch/x86/kernel/apic/hw_nmi.c +1 -1
@@ -19,7 +19,7 @@#include <linux/init.h> #include <linux/delay.h> -#ifdef CONFIG_HARDLOCKUP_DETECTOR +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF u64 hw_nmi_get_sample_period (int watchdog_thresh) {return (u64)(cpu_khz) *1000 * watchdog_thresh;
include/linux/nmi.h +20 -9
@@ -11,13 +11,21 @@#endif #ifdef CONFIG_LOCKUP_DETECTOR +void lockup_detector_init (void ); +#else +static inline void lockup_detector_init (void ) +{ +} +#endif + +#ifdef CONFIG_SOFTLOCKUP_DETECTOR extern void touch_softlockup_watchdog_sched (void );extern void touch_softlockup_watchdog (void );extern void touch_softlockup_watchdog_sync (void );extern void touch_all_softlockup_watchdogs (void );extern unsigned int softlockup_panic; -extern unsigned int hardlockup_panic; -void lockup_detector_init (void ); +extern int soft_watchdog_enabled; +extern atomic_t watchdog_park_in_progress;#else static inline void touch_softlockup_watchdog_sched (void ) {
@@ -31,9 +39,6 @@ static inline void touch_softlockup_watchdog_sync(void)static inline void touch_all_softlockup_watchdogs (void ) { } -static inline void lockup_detector_init (void ) -{ -}#endif #ifdef CONFIG_DETECT_HUNG_TASK
@@ -63,15 +68,18 @@ static inline void reset_hung_task_detector(void)#if defined(CONFIG_HARDLOCKUP_DETECTOR )extern void hardlockup_detector_disable (void ); +extern unsigned int hardlockup_panic;#else static inline void hardlockup_detector_disable (void ) {}#endif -#if defined(CONFIG_HARDLOCKUP_DETECTOR ) || defined(CONFIG_HAVE_NMI_WATCHDOG ) +#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF )extern void arch_touch_nmi_watchdog (void );#else +#if !defined(CONFIG_HAVE_NMI_WATCHDOG )static inline void arch_touch_nmi_watchdog (void ) {}#endif +#endif /** * touch_nmi_watchdog - restart NMI watchdog timeout.
@@ -141,15 +149,18 @@ static inline bool trigger_single_cpu_backtrace(int cpu) }#endif -#ifdef CONFIG_LOCKUP_DETECTOR +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF u64 hw_nmi_get_sample_period (int watchdog_thresh); +#endif + +#ifdef CONFIG_LOCKUP_DETECTOR extern int nmi_watchdog_enabled; -extern int soft_watchdog_enabled;extern int watchdog_user_enabled;extern int watchdog_thresh;extern unsigned long watchdog_enabled; +extern struct cpumask watchdog_cpumask;extern unsigned long *watchdog_cpumask_bits; -extern atomic_t watchdog_park_in_progress; +extern int __read_mostly watchdog_suspended;#ifdef CONFIG_SMP extern int sysctl_softlockup_all_cpu_backtrace;extern int sysctl_hardlockup_all_cpu_backtrace;
kernel/Makefile +1 -1
@@ -82,7 +82,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += debug/ obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o -obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog_hld.o +obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o obj-$(CONFIG_SECCOMP) += seccomp.o obj-$(CONFIG_RELAY) += relay.o obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
kernel/sysctl.c +18 -13
@@ -880,6 +880,14 @@ static struct ctl_table kern_table[] = {#endif }, { + .procname = "watchdog_cpumask", + .data = &watchdog_cpumask_bits, + .maxlen = NR_CPUS, + .mode = 0644, + .proc_handler = proc_watchdog_cpumask, + }, +#ifdef CONFIG_SOFTLOCKUP_DETECTOR + { .procname = "soft_watchdog", .data = &soft_watchdog_enabled, .maxlen = sizeof (int),
@@ -889,13 +897,6 @@ static struct ctl_table kern_table[] = { .extra2 = &one, }, { - .procname = "watchdog_cpumask", - .data = &watchdog_cpumask_bits, - .maxlen = NR_CPUS, - .mode = 0644, - .proc_handler = proc_watchdog_cpumask, - }, - { .procname = "softlockup_panic", .data = &softlockup_panic, .maxlen = sizeof(int),
@@ -904,27 +905,29 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, .extra2 = &one, }, -#ifdef CONFIG_HARDLOCKUP_DETECTOR +#ifdef CONFIG_SMP { - .procname = "hardlockup_panic", - .data = &hardlockup_panic, + .procname = "softlockup_all_cpu_backtrace", + .data = &sysctl_softlockup_all_cpu_backtrace, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &zero, .extra2 = &one, }, +#endif /* CONFIG_SMP */ #endif -#ifdef CONFIG_SMP +#ifdef CONFIG_HARDLOCKUP_DETECTOR { - .procname = "softlockup_all_cpu_backtrace", - .data = &sysctl_softlockup_all_cpu_backtrace, + .procname = "hardlockup_panic", + .data = &hardlockup_panic, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &zero, .extra2 = &one, }, +#ifdef CONFIG_SMP { .procname = "hardlockup_all_cpu_backtrace", .data = &sysctl_hardlockup_all_cpu_backtrace,
@@ -936,6 +939,8 @@ static struct ctl_table kern_table[] = { },#endif /* CONFIG_SMP */ #endif +#endif +#if defined(CONFIG_X86_LOCAL_APIC ) && defined(CONFIG_X86 ) { .procname = "unknown_nmi_panic",
kernel/watchdog.c +158 -85
318 lines not on this page · raw message
kernel/watchdog_hld.c +0 -32
@@ -22,39 +22,7 @@ static DEFINE_PER_CPU(bool, hard_watchdog_warn); static DEFINE_PER_CPU(bool, watchdog_nmi_touch); static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); -/* boot commands */ -/* -* Should we panic when a soft-lockup or hard-lockup occurs: -*/ -unsigned int __read_mostly hardlockup_panic = -CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE ;static unsigned long hardlockup_allcpu_dumped; -/* -* We may not want to enable hard lockup detection by default in all cases, -* for example when running the kernel as a guest on a hypervisor. In these -* cases this function can be called to disable hard lockup detection. This -* function should only be executed once by the boot processor before the -* kernel command line parameters are parsed, because otherwise it is not -* possible to override this in hardlockup_panic_setup(). -*/ -void hardlockup_detector_disable (void ) -{ - watchdog_enabled &= ~NMI_WATCHDOG_ENABLED ; -} - -static int __init hardlockup_panic_setup (char *str) -{ -if (!strncmp (str,"panic" ,5 )) - hardlockup_panic =1 ; -else if (!strncmp (str,"nopanic" ,7 )) - hardlockup_panic =0 ; -else if (!strncmp (str,"0" ,1 )) - watchdog_enabled &= ~NMI_WATCHDOG_ENABLED ; -else if (!strncmp (str,"1" ,1 )) - watchdog_enabled |=NMI_WATCHDOG_ENABLED ; -return 1 ; -} -__setup ("nmi_watchdog=" , hardlockup_panic_setup);void arch_touch_nmi_watchdog (void ) {
lib/Kconfig.debug +28 -17
83 lines not on this page · raw message
Signature · 1 line
2.11.0
Nicholas Piggin
reviewerRe: [PATCH v4 3/5] watchdog: split up config options
Quoted 13 lines · On Fri, 16 Jun 2017 16:57:13 +1000 Nicholas Piggin <[email protected]> wrote:
Split
SOFTLOCKUP_DETECTORfromLOCKUP_DETECTOR, and splitHARDLOCKUP_DETECTOR_PERFfromHARDLOCKUP_DETECTOR.
LOCKUP_DETECTORimplies the general boot, sysctl, and programming interfaces for the lockup detectors.An architecture that wants to use a hard lockup detector must define
HAVE_HARDLOCKUP_DETECTOR_PERForHAVE_HARDLOCKUP_DETECTOR_ARCH.Alternatively an arch can define
HAVE_NMI_WATCHDOG, which provides the minimumarch_touch_nmi_watchdog, and it otherwise does its own thing and does not implement theLOCKUP_DETECTORinterfaces.
Quoted 5 lines
sparc is unusual in that it has started to implement some of the interfaces, but not fully yet. It should probably be converted to a full
HAVE_HARDLOCKUP_DETECTOR_ARCH.Signed-off-by Nicholas Piggin <[email protected]>
I haven't worked out the nm10300 Kconfig warning, but in the meantime Andrew can you fold this patch in please?
Thanks,
Nick
--- arch/Kconfig | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
arch/Kconfig +1 -5
@@ -198,9 +198,6 @@ config HAVE_KPROBES_ON_FTRACE config HAVE_NMI bool -config HAVE_NMI_WATCHDOG - depends on HAVE_NMI - bool # # An arch should select this if it provides all these things: #
@@ -288,7 +285,6 @@ config HAVE_PERF_EVENTS_NMI subsystem. Also has support for calculating CPU cycle events to determine how many clock cycles in a given period. - config HAVE_HARDLOCKUP_DETECTOR_PERF bool depends on HAVE_PERF_EVENTS_NMI
@@ -297,6 +293,7 @@ config HAVE_HARDLOCKUP_DETECTOR_PERF detector. Must define HAVE_PERF_EVENTS_NMI. config HAVE_NMI_WATCHDOG + depends on HAVE_NMI bool help The arch provides a low level NMI watchdog. It provides
@@ -310,7 +307,6 @@ config HAVE_HARDLOCKUP_DETECTOR_ARCH a superset of the HAVE_NMI_WATCHDOG. It also conforms to config interfaces and parameters provided by hardlockup detector subsystem. - config HAVE_PERF_REGS bool help
Signature · 1 line
2.11.0
Nicholas Piggin
reviewerPATCH v4 4/5 watchdog: provide watchdog_reconfigure() for arch watchdogs
In reply to Nicholas PigginAfter reconfiguring watchdog sysctls etc., architecture specific watchdogs may not get all their parameters updated.
watchdog_reconfigure() can be implemented to pull the new values in and set the arch NMI watchdog.
--- kernel/watchdog.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
kernel/watchdog.c +25 -4
@@ -123,6 +123,11 @@ void __weak watchdog_nmi_disable(unsigned int cpu) { } +void __weak watchdog_nmi_reconfigure (void ) +{ +} + +#ifdef CONFIG_SOFTLOCKUP_DETECTOR /* Helper for online, unparked cpus. */
@@ -600,6 +605,12 @@ static void watchdog_disable_all_cpus(void) } } +static int watchdog_update_cpus (void ) +{ +return smpboot_update_cpumask_percpu_thread ( + &watchdog_threads, &watchdog_cpumask); +} +#else /* SOFTLOCKUP */ static int watchdog_park_threads (void ) {
@@ -619,6 +630,11 @@ static void watchdog_disable_all_cpus(void) { } +static int watchdog_update_cpus (void ) +{ +return 0 ; +} +static void set_sample_period (void ) { }
@@ -651,6 +667,8 @@ int lockup_detector_suspend(void) watchdog_enabled =0 ; } +watchdog_nmi_reconfigure (); +mutex_unlock (&watchdog_proc_mutex);return ret;
@@ -671,6 +689,8 @@ void lockup_detector_resume(void)if (watchdog_running && !watchdog_suspended)watchdog_unpark_threads (); +watchdog_nmi_reconfigure (); +mutex_unlock (&watchdog_proc_mutex);put_online_cpus (); }
@@ -696,6 +716,8 @@ static int proc_watchdog_update(void)else watchdog_disable_all_cpus (); +watchdog_nmi_reconfigure (); +return err; }
@@ -881,12 +903,11 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write,* a temporary cpumask, so we are likely not in a * position to do much else to make things better. */ -#ifdef CONFIG_SOFTLOCKUP_DETECTOR -if (smpboot_update_cpumask_percpu_thread ( - &watchdog_threads, &watchdog_cpumask) !=0 ) +if (watchdog_update_cpus () !=0 )pr_err ("cpumask update failed\n" ); -#endif } + +watchdog_nmi_reconfigure (); } out:mutex_unlock (&watchdog_proc_mutex);
Signature · 1 line
2.11.0
Andrew Morton
maintainerRe: [PATCH v4 4/5] watchdog: provide watchdog_reconfigure() for arch watchdogs
Quoted 6 lines · On Fri, 16 Jun 2017 16:57:14 +1000 Nicholas Piggin <[email protected]> wrote:
After reconfiguring watchdog sysctls etc., architecture specific watchdogs may not get all their parameters updated.
watchdog_reconfigure()can be implemented to pull the new values in and set the arch NMI watchdog.
I'll update the title and changelog to say "watchdog_nmi_reconfigure".
kernel/watchdog.c void __weak watchdog_nmi_disable(unsigned int cpu) · line 128
Quoted 9 lines
kernel/watchdog.c +3
-0@@ -123,6 +123,11 @@ void __weak watchdog_nmi_disable(unsigned int cpu) { } +void __weak watchdog_nmi_reconfigure (void ) +{ +}
Can we please get some documentation in here describing what it's for? How arch maintainers might use this? When and why it is called, what it must do? etc.
Nicholas Piggin
reviewerRe: [PATCH v4 4/5] watchdog: provide watchdog_reconfigure() for arch watchdogs
Quoted 10 lines · On Fri, 16 Jun 2017 11:24:07 -0700 Andrew Morton <[email protected]>…
Quoted 6 lines · On Fri, 16 Jun 2017 16:57:14 +1000 Nicholas Piggin <[email protected]> wrote:
After reconfiguring watchdog sysctls etc., architecture specific watchdogs may not get all their parameters updated.
watchdog_reconfigure()can be implemented to pull the new values in and set the arch NMI watchdog.I'll update the title and changelog to say "
watchdog_nmi_reconfigure".
Thanks.
Quoted 6 lines
Quoted 6 lines
kernel/watchdog.c +0
-0@@ -123,6 +123,11 @@ void __weak watchdog_nmi_disable(unsigned int cpu) { }
Quoted 7 lines
kernel/watchdog.c void __weak watchdog_nmi_disable(unsigned int cpu) · line 128
Quoted 3 lines
kernel/watchdog.c +3
-0+void __weak watchdog_nmi_reconfigure (void ) +{ +}Can we please get some documentation in here describing what it's for? How arch maintainers might use this? When and why it is called, what it must do? etc.
Good point, how's this?
--- kernel/watchdog.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
kernel/watchdog.c +15 -0
@@ -114,6 +114,10 @@ int __read_mostly watchdog_suspended;/* * These functions can be overridden if an architecture implements its * own hardlockup detector. +* +* watchdog_nmi_enable/disable can be implemented to start and stop when +* softlockup watchdog threads start and stop. The arch must select the +* SOFTLOCKUP_DETECTOR Kconfig. */ int __weak watchdog_nmi_enable (unsigned int cpu) {
@@ -123,6 +127,17 @@ void __weak watchdog_nmi_disable(unsigned int cpu) { } +/* +* watchdog_nmi_reconfigure can be implemented to be notified after any +* watchdog configuration change. The arch hardlockup watchdog should +* respond to the following variables: +* - nmi_watchdog_enabled +* - watchdog_thresh +* - watchdog_cpumask +* - sysctl_hardlockup_all_cpu_backtrace +* - hardlockup_panic +* - watchdog_suspended +*/ void __weak watchdog_nmi_reconfigure (void ) { }
Signature · 1 line
2.11.0
Nicholas Piggin
reviewerPATCH v4 5/5 powerpc/64s: implement arch-specific hardlockup watchdog
In reply to Nicholas PigginImplement an arch-speicfic watchdog rather than use the perf-based hardlockup detector.
The new watchdog takes the soft-NMI directly, rather than going through perf. Perf interrupts are to be made maskable in future, so that would prevent the perf detector from working in those regions.
Additionally, implement a SMP based detector where all CPUs watch one another by pinging a shared cpumask. This is because powerpc Book3S does not have a true periodic local NMI, but some platforms do implement a true NMI IPI.
If a CPU is stuck with interrupts hard disabled, the soft-NMI watchdog does not work, but the SMP watchdog will. Even on platforms without a true NMI IPI to get a good trace from the stuck CPU, other CPUs will notice the lockup sufficiently to report it and panic.
--- arch/powerpc/Kconfig | 7 +- arch/powerpc/include/asm/nmi.h | 11 + arch/powerpc/include/asm/smp.h | 2 + arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/exceptions-64s.S | 30 ++- arch/powerpc/kernel/kvm.c | 7 + arch/powerpc/kernel/setup_64.c | 19 -- arch/powerpc/kernel/smp.c | 20 +- arch/powerpc/kernel/watchdog.c | 388 +++++++++++++++++++++++++++++++++++ 9 files changed, 460 insertions(+), 25 deletions(-) create mode 100644 arch/powerpc/kernel/watchdog.c
arch/powerpc/Kconfig +4 -3
@@ -82,7 +82,7 @@ config NR_IRQS config NMI_IPI bool - depends on SMP && (DEBUGGER || KEXEC_CORE) + depends on SMP && (DEBUGGER || KEXEC_CORE || HARDLOCKUP_DETECTOR) default y config STACKTRACE_SUPPORT
@@ -197,12 +197,13 @@ config PPC select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select HAVE_MOD_ARCH_SPECIFIC - select HAVE_NMI if PERF_EVENTS + select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S) + select HAVE_HARDLOCKUP_DETECTOR_ARCH if (PPC64 && PPC_BOOK3S) select HAVE_OPROFILE select HAVE_OPTPROBES if PPC64 select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS_NMI if PPC64 - select HAVE_HARDLOCKUP_DETECTOR_PERF if HAVE_PERF_EVENTS_NMI + select HAVE_HARDLOCKUP_DETECTOR_PERF if HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_RCU_TABLE_FREE if SMP
arch/powerpc/include/asm/nmi.h +11 -0
@@ -1,4 +1,15 @@#ifndef _ASM_NMI_H#define _ASM_NMI_H +#ifdef CONFIG_HARDLOCKUP_DETECTOR +extern void arch_touch_nmi_watchdog (void ); + +extern void arch_trigger_cpumask_backtrace (const cpumask_t *mask, +bool exclude_self); +#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace + +#else +static inline void arch_touch_nmi_watchdog (void ) {} +#endif +#endif /* _ASM_NMI_H */
arch/powerpc/include/asm/smp.h +2 -0
@@ -55,6 +55,8 @@ struct smp_ops_t {int (*cpu_bootable)(unsigned int nr); }; +extern void smp_flush_nmi_ipi (u64 delay_us); +extern int smp_send_nmi_ipi (int cpu,void (*fn)(struct pt_regs *),u64 delay_us);extern void smp_send_debugger_break (void );extern void start_secondary_resume (void );extern void smp_generic_give_timebase (void );
arch/powerpc/kernel/Makefile +1 -0
@@ -40,6 +40,7 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o nvram_64.o firmware.o obj-$(CONFIG_VDSO32) += vdso32/ +obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o
arch/powerpc/kernel/exceptions-64s.S +28 -2
@@ -1273,6 +1273,31 @@ EXC_REAL_NONE(0x1800, 0x100) EXC_VIRT_NONE(0x5800, 0x100) #endif +#if defined(CONFIG_HARDLOCKUP_DETECTOR) && defined(CONFIG_HAVE_HARDLOCKUP_DETECTOR_ARCH) + +#define MASKED_DEC_HANDLER_LABEL 3f + +#define MASKED_DEC_HANDLER(_H) \ +3: /* soft-nmi */ \ + std r12,PACA_EXGEN+EX_R12(r13); \ + GET_SCRATCH0(r10); \ + std r10,PACA_EXGEN+EX_R13(r13); \ + EXCEPTION_PROLOG_PSERIES_1(soft_nmi_common, _H) + +EXC_COMMON_BEGIN(soft_nmi_common) + mr r10,r1 + ld r1,PACAEMERGSP(r13) + ld r1,PACA_NMI_EMERG_SP(r13) + subi r1,r1,INT_FRAME_SIZE + EXCEPTION_COMMON_NORET_STACK(PACA_EXGEN, 0x900, + system_reset, soft_nmi_interrupt, + ADD_NVGPRS;ADD_RECONCILE) + b ret_from_except + +#else +#define MASKED_DEC_HANDLER_LABEL 2f /* normal return */ +#define MASKED_DEC_HANDLER(_H) +#endif /* * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
@@ -1295,7 +1320,7 @@ masked_##_H##interrupt: \ lis r10,0x7fff; \ ori r10,r10,0xffff; \ mtspr SPRN_DEC,r10; \ - b 2f; \ + b MASKED_DEC_HANDLER_LABEL; \ 1: cmpwi r10,PACA_IRQ_DBELL; \ beq 2f; \ cmpwi r10,PACA_IRQ_HMI; \
@@ -1310,7 +1335,8 @@ masked_##_H##interrupt: \ ld r11,PACA_EXGEN+EX_R11(r13); \ GET_SCRATCH0(r13); \ ##_H##rfid; \ - b . + b .; \ + MASKED_DEC_HANDLER(_H) /* * Real mode exceptions actually use this too, but alternate
arch/powerpc/kernel/kvm.c +7 -0
@@ -25,6 +25,7 @@#include <linux/kvm_para.h> #include <linux/slab.h> #include <linux/of.h> +#include <linux/nmi.h> /* hardlockup_detector_disable() */ #include <asm/reg.h> #include <asm/sections.h>
@@ -718,6 +719,12 @@ static __init void kvm_free_tmp(void)static int __init kvm_guest_init (void ) { +/* +* The hardlockup detector is likely to get false positives in +* KVM guests, so disable it by default. +*/ +hardlockup_detector_disable (); +if (!kvm_para_available ()) goto free_tmp;
arch/powerpc/kernel/setup_64.c +0 -19
@@ -726,22 +726,3 @@ unsigned long memory_block_size_bytes(void)struct ppc_pci_io ppc_pci_io;EXPORT_SYMBOL (ppc_pci_io);#endif - -#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF -u64 hw_nmi_get_sample_period (int watchdog_thresh) -{ -return ppc_proc_freq * watchdog_thresh; -} - -/* -* The hardlockup detector breaks PMU event based branches and is likely -* to get false positives in KVM guests, so disable it by default. -*/ -static int __init disable_hardlockup_detector (void ) -{ -hardlockup_detector_disable (); - -return 0 ; -} -early_initcall (disable_hardlockup_detector); -#endif
arch/powerpc/kernel/smp.c +19 -1
@@ -433,13 +433,31 @@ static void do_smp_send_nmi_ipi(int cpu) } } +void smp_flush_nmi_ipi (u64 delay_us) +{ +unsigned long flags; + +nmi_ipi_lock_start (&flags); +while (nmi_ipi_busy_count) { +nmi_ipi_unlock_end (&flags); +udelay (1 ); +if (delay_us) { + delay_us--; +if (!delay_us) +return ; + } +nmi_ipi_lock_start (&flags); + } +nmi_ipi_unlock_end (&flags); +} +/* * - cpu is the target CPU (must not be this CPU), or NMI_IPI_ALL_OTHERS. * - fn is the target callback function. * - delay_us > 0 is the delay before giving up waiting for targets to * enter the handler, == 0 specifies indefinite delay. */ -static int smp_send_nmi_ipi (int cpu,void (*fn)(struct pt_regs *),u64 delay_us) +int smp_send_nmi_ipi (int cpu,void (*fn)(struct pt_regs *),u64 delay_us) {unsigned long flags;int me =raw_smp_processor_id ();
arch/powerpc/kernel/watchdog.c new file +388 -0
388 lines not on this page · raw message
Signature · 1 line
2.11.0
(adding Andrew)
Quoted 7 lines · Nicholas Piggin
This is the latest series to make the hardlockup watchdog more easily replaceable by arch code. The last patch provides some justification for why we want to do this (existing sparc watchdog is another that could benefit).
Since last time, we tidied up the
Kconfigapproach so it was not so jumbled -- Thanks Don and Babu for help and suggestions there.
Thanks Nick! I think this version is good enough for now.
Quoted 8 lines
Since last posting the powerpc patch, I re-added the soft-NMI watchdog, but have it using the emergency stack so we can always avoid the process stacks when perf interrupts are soft-masked.
I'm not sure of the best strategy to merge this. The powerpc watchdog is too much to carry anywhere but powerpc tree now, and watchdog patches seem to go via Andrew...
Andrew, suggestions here?
Quoted 42 lines
Thanks,
NickNicholas Piggin (5):
watchdog: remove unused declaration
watchdog: introducearch_touch_nmi_watchdog()
watchdog: split up config options
watchdog: providewatchdog_reconfigure()for arch watchdogs powerpc/64s: implement arch-specific hardlockup watchdogarch/Kconfig | 23 ++ arch/blackfin/include/asm/nmi.h | 2 + arch/blackfin/kernel/nmi.c | 2 +- arch/mn10300/include/asm/nmi.h | 2 + arch/mn10300/kernel/mn10300-watchdog-low.S | 8 +- arch/mn10300/kernel/mn10300-watchdog.c | 2 +- arch/powerpc/Kconfig | 6 +- arch/powerpc/include/asm/nmi.h | 11 + arch/powerpc/include/asm/smp.h | 2 + arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/exceptions-64s.S | 30 ++- arch/powerpc/kernel/kvm.c | 7 + arch/powerpc/kernel/setup_64.c | 19 -- arch/powerpc/kernel/smp.c | 20 +- arch/powerpc/kernel/watchdog.c | 388 +++++++++++++++++++++++++++++ arch/sparc/include/asm/nmi.h | 1 + arch/sparc/kernel/nmi.c | 6 +- arch/x86/Kconfig | 1 + arch/x86/kernel/apic/hw_nmi.c | 2 +- include/linux/nmi.h | 57 +++-- kernel/Makefile | 2 +- kernel/sysctl.c | 31 ++- kernel/watchdog.c | 268 +++++++++++++------- kernel/watchdog_hld.c | 37 +-- lib/Kconfig.debug | 45 ++-- 25 files changed, 763 insertions(+), 210 deletions(-) create mode 100644 arch/powerpc/kernel/watchdog.cSignature · 1 line
2.11.0
Tested on sparc:
Reviewed patch #1, #2, #3
Quoted 67 lines · Don Zickus
(adding Andrew)
Quoted 7 lines · Nicholas Piggin
This is the latest series to make the hardlockup watchdog more easily replaceable by arch code. The last patch provides some justification for why we want to do this (existing sparc watchdog is another that could benefit).
Since last time, we tidied up the
Kconfigapproach so it was not so jumbled -- Thanks Don and Babu for help and suggestions there.Thanks Nick! I think this version is good enough for now.
Quoted 7 lines
Since last posting the powerpc patch, I re-added the soft-NMI watchdog, but have it using the emergency stack so we can always avoid the process stacks when perf interrupts are soft-masked.
I'm not sure of the best strategy to merge this. The powerpc watchdog is too much to carry anywhere but powerpc tree now, and watchdog patches seem to go via Andrew...
Andrew, suggestions here?
Reviewed-by Don Zickus <[email protected]>Acked-by Don Zickus <[email protected]>Quoted 41 lines
Thanks,
NickNicholas Piggin (5):
watchdog: remove unused declaration
watchdog: introducearch_touch_nmi_watchdog()
watchdog: split up config options
watchdog: providewatchdog_reconfigure()for arch watchdogs powerpc/64s: implement arch-specific hardlockup watchdogarch/Kconfig | 23 ++ arch/blackfin/include/asm/nmi.h | 2 + arch/blackfin/kernel/nmi.c | 2 +- arch/mn10300/include/asm/nmi.h | 2 + arch/mn10300/kernel/mn10300-watchdog-low.S | 8 +- arch/mn10300/kernel/mn10300-watchdog.c | 2 +- arch/powerpc/Kconfig | 6 +- arch/powerpc/include/asm/nmi.h | 11 + arch/powerpc/include/asm/smp.h | 2 + arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/exceptions-64s.S | 30 ++- arch/powerpc/kernel/kvm.c | 7 + arch/powerpc/kernel/setup_64.c | 19 -- arch/powerpc/kernel/smp.c | 20 +- arch/powerpc/kernel/watchdog.c | 388 +++++++++++++++++++++++++++++ arch/sparc/include/asm/nmi.h | 1 + arch/sparc/kernel/nmi.c | 6 +- arch/x86/Kconfig | 1 + arch/x86/kernel/apic/hw_nmi.c | 2 +- include/linux/nmi.h | 57 +++-- kernel/Makefile | 2 +- kernel/sysctl.c | 31 ++- kernel/watchdog.c | 268 +++++++++++++------- kernel/watchdog_hld.c | 37 +-- lib/Kconfig.debug | 45 ++-- 25 files changed, 763 insertions(+), 210 deletions(-)create mode 100644
arch/powerpc/kernel/watchdog.cSignature · 1 line
2.11.0