From d8939d82cb68a637d1ff9c290e7e1a81a984ca61 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sun, 15 Aug 2004 02:06:27 +0000 Subject: [PATCH] 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 --- sys/kern/subr_kdb.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index e2ea2770dcb1..4e53c89ac264 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--;