nmi.h 6.7 KB

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