diff options
author | rwatson <rwatson@FreeBSD.org> | 2004-08-15 02:06:27 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2004-08-15 02:06:27 +0000 |
commit | b3113cfdfe2dba0017cb48d90a506c9e584a28b1 (patch) | |
tree | dfac1a4fe94a8e589e9163fe93d88bbe109cdcab /sys | |
parent | e2cfa215cf52959df773bf83451fa42161329f6d (diff) | |
download | FreeBSD-src-b3113cfdfe2dba0017cb48d90a506c9e584a28b1.zip FreeBSD-src-b3113cfdfe2dba0017cb48d90a506c9e584a28b1.tar.gz |
Add a new sysctl, debug.kdb.stop_cpus, which controls whether or not we
attempt to IPI other cpus when entering the debugger in order to stop
them while in the debugger. The default remains to issue the stop;
however, that can result in a hang if another cpu has interrupts disabled
and is spinning, since the IPI won't be received and the KDB will wait
indefinitely. We probably need to add a timeout, but this is a useful
stopgap in the mean time.
Reviewed by: marcel
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/subr_kdb.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index e2ea277..4e53c89 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -66,6 +66,18 @@ SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, 0, 0, SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, 0, 0, kdb_sysctl_enter, "I", "set to enter the debugger"); +/* + * Flag indicating whether or not to IPI the other CPUs to stop them on + * entering the debugger. Sometimes, this will result in a deadlock as + * stop_cpus() waits for the other cpus to stop, so we allow it to be + * disabled. + */ +#ifdef SMP +static int kdb_stop_cpus = 1; +SYSCTL_INT(_debug_kdb, OID_AUTO, stop_cpus, CTLTYPE_INT | CTLFLAG_RW, + &kdb_stop_cpus, 0, ""); +#endif + static int kdb_sysctl_available(SYSCTL_HANDLER_ARGS) { @@ -374,6 +386,9 @@ kdb_thr_select(struct thread *thr) int kdb_trap(int type, int code, struct trapframe *tf) { +#ifdef SMP + int did_stop_cpus; +#endif int handled; if (kdb_dbbe == NULL || kdb_dbbe->dbbe_trap == NULL) @@ -392,7 +407,8 @@ kdb_trap(int type, int code, struct trapframe *tf) kdb_thr_select(curthread); #ifdef SMP - stop_cpus(PCPU_GET(other_cpus)); + if ((did_stop_cpus = kdb_stop_cpus) != 0) + stop_cpus(PCPU_GET(other_cpus)); #endif /* Let MD code do its thing first... */ @@ -401,7 +417,8 @@ kdb_trap(int type, int code, struct trapframe *tf) handled = kdb_dbbe->dbbe_trap(type, code); #ifdef SMP - restart_cpus(stopped_cpus); + if (did_stop_cpus) + restart_cpus(stopped_cpus); #endif kdb_active--; |