at v4.18 6.6 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * linux/include/linux/nmi.h 4 */ 5#ifndef LINUX_NMI_H 6#define LINUX_NMI_H 7 8#include <linux/sched.h> 9#include <asm/irq.h> 10#if defined(CONFIG_HAVE_NMI_WATCHDOG) 11#include <asm/nmi.h> 12#endif 13 14#ifdef CONFIG_LOCKUP_DETECTOR 15void lockup_detector_init(void); 16void lockup_detector_soft_poweroff(void); 17void lockup_detector_cleanup(void); 18bool is_hardlockup(void); 19 20extern int watchdog_user_enabled; 21extern int nmi_watchdog_user_enabled; 22extern int soft_watchdog_user_enabled; 23extern int watchdog_thresh; 24extern unsigned long watchdog_enabled; 25 26extern struct cpumask watchdog_cpumask; 27extern unsigned long *watchdog_cpumask_bits; 28#ifdef CONFIG_SMP 29extern int sysctl_softlockup_all_cpu_backtrace; 30extern int sysctl_hardlockup_all_cpu_backtrace; 31#else 32#define sysctl_softlockup_all_cpu_backtrace 0 33#define sysctl_hardlockup_all_cpu_backtrace 0 34#endif /* !CONFIG_SMP */ 35 36#else /* CONFIG_LOCKUP_DETECTOR */ 37static inline void lockup_detector_init(void) { } 38static inline void lockup_detector_soft_poweroff(void) { } 39static inline void lockup_detector_cleanup(void) { } 40#endif /* !CONFIG_LOCKUP_DETECTOR */ 41 42#ifdef CONFIG_SOFTLOCKUP_DETECTOR 43extern void touch_softlockup_watchdog_sched(void); 44extern void touch_softlockup_watchdog(void); 45extern void touch_softlockup_watchdog_sync(void); 46extern void touch_all_softlockup_watchdogs(void); 47extern unsigned int softlockup_panic; 48#else 49static inline void touch_softlockup_watchdog_sched(void) { } 50static inline void touch_softlockup_watchdog(void) { } 51static inline void touch_softlockup_watchdog_sync(void) { } 52static inline void touch_all_softlockup_watchdogs(void) { } 53#endif 54 55#ifdef CONFIG_DETECT_HUNG_TASK 56void reset_hung_task_detector(void); 57#else 58static inline void reset_hung_task_detector(void) { } 59#endif 60 61/* 62 * The run state of the lockup detectors is controlled by the content of the 63 * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit - 64 * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector. 65 * 66 * 'watchdog_user_enabled', 'nmi_watchdog_user_enabled' and 67 * 'soft_watchdog_user_enabled' are variables that are only used as an 68 * 'interface' between the parameters in /proc/sys/kernel and the internal 69 * state bits in 'watchdog_enabled'. The 'watchdog_thresh' variable is 70 * handled differently because its value is not boolean, and the lockup 71 * detectors are 'suspended' while 'watchdog_thresh' is equal zero. 72 */ 73#define NMI_WATCHDOG_ENABLED_BIT 0 74#define SOFT_WATCHDOG_ENABLED_BIT 1 75#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT) 76#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) 77 78#if defined(CONFIG_HARDLOCKUP_DETECTOR) 79extern void hardlockup_detector_disable(void); 80extern unsigned int hardlockup_panic; 81#else 82static inline void hardlockup_detector_disable(void) {} 83#endif 84 85#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR) 86# define NMI_WATCHDOG_SYSCTL_PERM 0644 87#else 88# define NMI_WATCHDOG_SYSCTL_PERM 0444 89#endif 90 91#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) 92extern void arch_touch_nmi_watchdog(void); 93extern void hardlockup_detector_perf_stop(void); 94extern void hardlockup_detector_perf_restart(void); 95extern void hardlockup_detector_perf_disable(void); 96extern void hardlockup_detector_perf_enable(void); 97extern void hardlockup_detector_perf_cleanup(void); 98extern int hardlockup_detector_perf_init(void); 99#else 100static inline void hardlockup_detector_perf_stop(void) { } 101static inline void hardlockup_detector_perf_restart(void) { } 102static inline void hardlockup_detector_perf_disable(void) { } 103static inline void hardlockup_detector_perf_enable(void) { } 104static inline void hardlockup_detector_perf_cleanup(void) { } 105# if !defined(CONFIG_HAVE_NMI_WATCHDOG) 106static inline int hardlockup_detector_perf_init(void) { return -ENODEV; } 107static inline void arch_touch_nmi_watchdog(void) {} 108# else 109static inline int hardlockup_detector_perf_init(void) { return 0; } 110# endif 111#endif 112 113void watchdog_nmi_stop(void); 114void watchdog_nmi_start(void); 115int watchdog_nmi_probe(void); 116 117/** 118 * touch_nmi_watchdog - restart NMI watchdog timeout. 119 * 120 * If the architecture supports the NMI watchdog, touch_nmi_watchdog() 121 * may be used to reset the timeout - for code which intentionally 122 * disables interrupts for a long time. This call is stateless. 123 */ 124static inline void touch_nmi_watchdog(void) 125{ 126 arch_touch_nmi_watchdog(); 127 touch_softlockup_watchdog(); 128} 129 130/* 131 * Create trigger_all_cpu_backtrace() out of the arch-provided 132 * base function. Return whether such support was available, 133 * to allow calling code to fall back to some other mechanism: 134 */ 135#ifdef arch_trigger_cpumask_backtrace 136static inline bool trigger_all_cpu_backtrace(void) 137{ 138 arch_trigger_cpumask_backtrace(cpu_online_mask, false); 139 return true; 140} 141 142static inline bool trigger_allbutself_cpu_backtrace(void) 143{ 144 arch_trigger_cpumask_backtrace(cpu_online_mask, true); 145 return true; 146} 147 148static inline bool trigger_cpumask_backtrace(struct cpumask *mask) 149{ 150 arch_trigger_cpumask_backtrace(mask, false); 151 return true; 152} 153 154static inline bool trigger_single_cpu_backtrace(int cpu) 155{ 156 arch_trigger_cpumask_backtrace(cpumask_of(cpu), false); 157 return true; 158} 159 160/* generic implementation */ 161void nmi_trigger_cpumask_backtrace(const cpumask_t *mask, 162 bool exclude_self, 163 void (*raise)(cpumask_t *mask)); 164bool nmi_cpu_backtrace(struct pt_regs *regs); 165 166#else 167static inline bool trigger_all_cpu_backtrace(void) 168{ 169 return false; 170} 171static inline bool trigger_allbutself_cpu_backtrace(void) 172{ 173 return false; 174} 175static inline bool trigger_cpumask_backtrace(struct cpumask *mask) 176{ 177 return false; 178} 179static inline bool trigger_single_cpu_backtrace(int cpu) 180{ 181 return false; 182} 183#endif 184 185#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF 186u64 hw_nmi_get_sample_period(int watchdog_thresh); 187#endif 188 189#if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \ 190 defined(CONFIG_HARDLOCKUP_DETECTOR) 191void watchdog_update_hrtimer_threshold(u64 period); 192#else 193static inline void watchdog_update_hrtimer_threshold(u64 period) { } 194#endif 195 196struct ctl_table; 197extern int proc_watchdog(struct ctl_table *, int , 198 void __user *, size_t *, loff_t *); 199extern int proc_nmi_watchdog(struct ctl_table *, int , 200 void __user *, size_t *, loff_t *); 201extern int proc_soft_watchdog(struct ctl_table *, int , 202 void __user *, size_t *, loff_t *); 203extern int proc_watchdog_thresh(struct ctl_table *, int , 204 void __user *, size_t *, loff_t *); 205extern int proc_watchdog_cpumask(struct ctl_table *, int, 206 void __user *, size_t *, loff_t *); 207 208#ifdef CONFIG_HAVE_ACPI_APEI_NMI 209#include <asm/nmi.h> 210#endif 211 212#endif