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
This commit is contained in:
Robert Watson 2004-08-15 02:06:27 +00:00
parent adb03c6788
commit d8939d82cb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=133737

View file

@ -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--;