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