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"
10 unsigned watchdog_local_timer_ticks
= 0U;
11 struct arch_watchdog
*watchdog
;
14 static void lockup_check(struct nmi_frame
* frame
)
16 /* FIXME this should be CPU local */
17 static unsigned no_ticks
;
18 static unsigned last_tick_count
= (unsigned) -1;
21 * when debugging on serial console, printing takes a lot of time some
22 * times while the kernel is certainly not locked up. We don't want to
23 * report a lockup in such situation
25 if (serial_debug_active
)
28 if (last_tick_count
!= watchdog_local_timer_ticks
) {
30 printf("watchdog : kernel unlocked\n");
33 /* we are still ticking, everything seems good */
34 last_tick_count
= watchdog_local_timer_ticks
;
39 * if watchdog_local_timer_ticks didn't changed since last time, give it
40 * some more time and only if it still dead, trigger the watchdog alarm
42 if (++no_ticks
< 10) {
44 printf("WARNING watchdog : possible kernel lockup\n");
48 /* if we get this far, the kernel is locked up */
49 arch_watchdog_lockup(frame
);
52 void nmi_watchdog_handler(struct nmi_frame
* frame
)
56 * Do not check for lockups while profiling, it is extremely likely that
57 * a false positive is detected if the frequency is high
59 if (watchdog_enabled
&& !sprofiling
)
62 nmi_sprofile_handler(frame
);
64 if ((watchdog_enabled
|| sprofiling
) && watchdog
->reinit
)
65 watchdog
->reinit(cpuid
);
67 if (watchdog_enabled
) {
70 watchdog
->reinit(cpuid
);
75 int nmi_watchdog_start_profiling(const unsigned freq
)
79 /* if watchdog hasn't been enabled, we must enable it now */
80 if (!watchdog_enabled
) {
81 if (arch_watchdog_init())
85 if (!watchdog
->profile_init
) {
86 printf("WARNING NMI watchdog profiling not supported\n");
87 nmi_watchdog_stop_profiling();
91 err
= watchdog
->profile_init(freq
);
95 watchdog
->resetval
= watchdog
->profile_resetval
;
100 void nmi_watchdog_stop_profiling(void)
103 * if we do not rearm the NMI source, we are done, if we want to keep
104 * the watchdog running, we reset is to its normal value
108 watchdog
->resetval
= watchdog
->watchdog_resetval
;
110 if (!watchdog_enabled
)
111 arch_watchdog_stop();