2 * This is arch independent NMI watchdog implementation part. It is used to
3 * detect kernel lockups and help debugging. each architecture must add its own
4 * low level code that triggers periodic checks
8 #include "arch/i386/glo.h"
11 unsigned watchdog_local_timer_ticks
= 0U;
12 struct arch_watchdog
*watchdog
;
15 static void lockup_check(struct nmi_frame
* frame
)
17 /* FIXME this should be CPU local */
18 static unsigned no_ticks
;
19 static unsigned last_tick_count
= (unsigned) -1;
22 * when debugging on serial console, printing takes a lot of time some
23 * times while the kernel is certainly not locked up. We don't want to
24 * report a lockup in such situation
26 if (serial_debug_active
)
29 if (last_tick_count
!= watchdog_local_timer_ticks
) {
31 printf("watchdog : kernel unlocked\n");
34 /* we are still ticking, everything seems good */
35 last_tick_count
= watchdog_local_timer_ticks
;
40 * if watchdog_local_timer_ticks didn't changed since last time, give it
41 * some more time and only if it still dead, trigger the watchdog alarm
43 if (++no_ticks
< 10) {
45 printf("WARNING watchdog : possible kernel lockup\n");
49 /* if we get this far, the kernel is locked up */
50 arch_watchdog_lockup(frame
);
53 void nmi_watchdog_handler(struct nmi_frame
* frame
)
57 * Do not check for lockups while profiling, it is extremely likely that
58 * a false positive is detected if the frequency is high
60 if (watchdog_enabled
&& !sprofiling
)
63 nmi_sprofile_handler(frame
);
65 if ((watchdog_enabled
|| sprofiling
) && watchdog
->reinit
)
66 watchdog
->reinit(cpuid
);
68 if (watchdog_enabled
) {
71 watchdog
->reinit(cpuid
);
76 int nmi_watchdog_start_profiling(const unsigned freq
)
80 /* if watchdog hasn't been enabled, we must enable it now */
81 if (!watchdog_enabled
) {
82 if (arch_watchdog_init())
86 if (!watchdog
->profile_init
) {
87 printf("WARNING NMI watchdog profiling not supported\n");
88 nmi_watchdog_stop_profiling();
92 err
= watchdog
->profile_init(freq
);
96 watchdog
->resetval
= watchdog
->profile_resetval
;
101 void nmi_watchdog_stop_profiling(void)
104 * if we do not rearm the NMI source, we are done, if we want to keep
105 * the watchdog running, we reset is to its normal value
109 watchdog
->resetval
= watchdog
->watchdog_resetval
;
111 if (!watchdog_enabled
)
112 arch_watchdog_stop();