summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-08-15 02:06:27 +0000
committerrwatson <rwatson@FreeBSD.org>2004-08-15 02:06:27 +0000
commitb3113cfdfe2dba0017cb48d90a506c9e584a28b1 (patch)
treedfac1a4fe94a8e589e9163fe93d88bbe109cdcab
parente2cfa215cf52959df773bf83451fa42161329f6d (diff)
downloadFreeBSD-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
-rw-r--r--sys/kern/subr_kdb.c21
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--;
OpenPOWER on IntegriCloud