diff options
author | obrien <obrien@FreeBSD.org> | 2005-02-27 22:31:35 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2005-02-27 22:31:35 +0000 |
commit | 4aa4ed03c6314d7d1eae1025e13e2c7a112ada0e (patch) | |
tree | eafb33f3ce7b3460941a45870fa259439ef4e466 | |
parent | 3effafb90a0313f12aa00f9ba4d42ef58deed370 (diff) | |
download | FreeBSD-src-4aa4ed03c6314d7d1eae1025e13e2c7a112ada0e.zip FreeBSD-src-4aa4ed03c6314d7d1eae1025e13e2c7a112ada0e.tar.gz |
MFi386: rev 1.3:
- Add debug.watchdog tunable, so we can specify watchdog CPU from loader
which will help to debug hangs on boot.
- Remove 'U' from debug.watchdog sysctl definition, so if we set it to '-1'
it really shows '-1'.
- Fix comment.
-rw-r--r-- | sys/amd64/amd64/mp_watchdog.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/sys/amd64/amd64/mp_watchdog.c b/sys/amd64/amd64/mp_watchdog.c index b3b5d9e..4a1d88e 100644 --- a/sys/amd64/amd64/mp_watchdog.c +++ b/sys/amd64/amd64/mp_watchdog.c @@ -49,11 +49,11 @@ #include <machine/mp_watchdog.h> /* - * mp_swatchdog hijacks the idle thread on a specified CPU, prevents new work + * mp_watchdog hijacks the idle thread on a specified CPU, prevents new work * from being scheduled there, and uses it as a "watchdog" to detect kernel * failure on other CPUs. This is made reasonable by inclusion of logical * processors in Xeon hardware. The watchdog is configured by setting the - * debug.watchdog_cpu sysctl to the CPU of interest. A callout will then + * debug.watchdog sysctl/tunable to the CPU of interest. A callout will then * begin executing reseting a timer that is gradually lowered by the watching * thread. If the timer reaches 0, the watchdog fires by ether dropping * directly to the debugger, or by sending an NMI IPI to the boot processor. @@ -68,11 +68,14 @@ static int watchdog_dontfire = 1; static int watchdog_timer = -1; static int watchdog_nmi = 1; +TUNABLE_INT("debug.watchdog", &watchdog_cpu); SYSCTL_INT(_debug, OID_AUTO, watchdog_nmi, CTLFLAG_RW, &watchdog_nmi, 0, "IPI the boot processor with an NMI to enter the debugger"); static struct callout watchdog_callout; +static void watchdog_change(int wdcpu); + /* * Number of seconds before the watchdog will fire if the callout fails to * reset the timer. @@ -84,6 +87,8 @@ watchdog_init(void *arg) { callout_init(&watchdog_callout, CALLOUT_MPSAFE); + if (watchdog_cpu != -1) + watchdog_change(watchdog_cpu); } /* @@ -108,6 +113,27 @@ watchdog_function(void *arg) } SYSINIT(watchdog_init, SI_SUB_DRIVERS, SI_ORDER_ANY, watchdog_init, NULL); +static void +watchdog_change(int wdcpu) +{ + + if (wdcpu == -1 || wdcpu == 0xffffffff) { + /* + * Disable the watcdog. + */ + watchdog_cpu = -1; + watchdog_dontfire = 1; + callout_stop(&watchdog_callout); + printf("watchdog stopped\n"); + } else { + watchdog_timer = WATCHDOG_THRESHOLD; + watchdog_dontfire = 0; + watchdog_cpu = wdcpu; + callout_reset(&watchdog_callout, 1 * hz, watchdog_function, + NULL); + } +} + /* * This sysctl sets which CPU is the watchdog CPU. Set to -1 or 0xffffffff * to disable the watchdog. @@ -122,27 +148,12 @@ sysctl_watchdog(SYSCTL_HANDLER_ARGS) if (error) return (error); - if (req->newptr != NULL) { - if (temp == -1 || temp == 0xffffffff) { - /* - * Disable the watcdog. - */ - watchdog_cpu = -1; - watchdog_dontfire = 1; - callout_stop(&watchdog_callout); - printf("watchdog stopped\n"); - } else { - watchdog_timer = WATCHDOG_THRESHOLD; - watchdog_dontfire = 0; - watchdog_cpu = temp; - callout_reset(&watchdog_callout, 1 * hz, - watchdog_function, NULL); - } - } + if (req->newptr != NULL) + watchdog_change(temp); return (0); } SYSCTL_PROC(_debug, OID_AUTO, watchdog, CTLTYPE_INT|CTLFLAG_RW, 0, 0, - sysctl_watchdog, "IU", ""); + sysctl_watchdog, "I", ""); /* * A badly behaved sysctl that leaks the sched lock when written to. Then |