minix/kernel/watchdog.c

52 lines
1.4 KiB
C

/*
* This is arch independent NMI watchdog implementaion part. It is used to
* detect kernel lockups and help debugging. each architecture must add its own
* low level code that triggers periodic checks
*/
#include "watchdog.h"
unsigned watchdog_local_timer_ticks = 0U;
struct arch_watchdog *watchdog;
int watchdog_enabled;
void nmi_watchdog_handler(struct nmi_frame * frame)
{
/* FIXME this should be CPU local */
static unsigned no_ticks;
static unsigned last_tick_count = (unsigned) -1;
/*
* when debugging on serial console, printing takes a lot of time some
* times while the kernel is certainly not locked up. We don't want to
* report a lockup in such situation
*/
if (serial_debug_active)
goto reset_and_continue;
if (last_tick_count != watchdog_local_timer_ticks) {
if (no_ticks == 1) {
printf("watchdog : kernel unlocked\n");
no_ticks = 0;
}
/* we are still ticking, everything seems good */
last_tick_count = watchdog_local_timer_ticks;
goto reset_and_continue;
}
/*
* if watchdog_local_timer_ticks didn't changed since last time, give it
* some more time and only if it still dead, trigger the watchdog alarm
*/
if (++no_ticks < 10) {
if (no_ticks == 1)
printf("WARNING watchdog : possible kernel lockup\n");
goto reset_and_continue;
}
arch_watchdog_lockup(frame);
reset_and_continue:
if (watchdog->reinit)
watchdog->reinit(cpuid);
}