diff options
author | attilio <attilio@FreeBSD.org> | 2011-09-04 13:07:02 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2011-09-04 13:07:02 +0000 |
commit | ef6fc882acfd1cfb8bbb5c729679924a4be0d4b5 (patch) | |
tree | 489b30b9eaa9d19fb2fee3c6cf94f7609324f692 | |
parent | b1c63cf9da188d614a4a5297f84d2212cbbe9aaf (diff) | |
download | FreeBSD-src-ef6fc882acfd1cfb8bbb5c729679924a4be0d4b5.zip FreeBSD-src-ef6fc882acfd1cfb8bbb5c729679924a4be0d4b5.tar.gz |
Interrupts are disabled/enabled when entering and exiting the KDB context.
While this is generally good, it brings along a serie of problems,
like clocks going off sync and in presence of SW_WATCHDOG, watchdogs
firing without a good reason (missed hardclock wdog ticks update).
Fix the latter by kicking the watchdog just before to re-enable the interrupts.
Also, while here, not rely on users to stop the watchdog manually when
entering DDB but do that when entering KDB context.
Sponsored by: Sandvine Incorporated
Reviewed by: emaste, rstone
Approved by: re (kib)
MFC after: 1 week
-rw-r--r-- | sys/kern/subr_kdb.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index 76b37a9..2ee7dc6 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include "opt_kdb.h" #include "opt_stack.h" +#include "opt_watchdog.h" #include <sys/param.h> #include <sys/systm.h> @@ -41,6 +42,9 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <sys/stack.h> #include <sys/sysctl.h> +#ifdef SW_WATCHDOG +#include <sys/watchdog.h> +#endif #include <machine/kdb.h> #include <machine/pcb.h> @@ -587,6 +591,9 @@ kdb_trap(int type, int code, struct trapframe *tf) cpuset_t other_cpus; #endif struct kdb_dbbe *be; +#ifdef SW_WATCHDOG + u_int wdoglvt; +#endif register_t intr; int handled; @@ -600,6 +607,10 @@ kdb_trap(int type, int code, struct trapframe *tf) intr = intr_disable(); +#ifdef SW_WATCHDOG + wdoglvt = wdog_kern_last_timeout(); + wdog_kern_pat(WD_TO_NEVER); +#endif #ifdef SMP other_cpus = all_cpus; CPU_CLR(PCPU_GET(cpuid), &other_cpus); @@ -631,6 +642,9 @@ kdb_trap(int type, int code, struct trapframe *tf) #ifdef SMP restart_cpus(stopped_cpus); #endif +#ifdef SW_WATCHDOG + wdog_kern_pat(wdoglvt); +#endif intr_restore(intr); |