diff options
author | jhb <jhb@FreeBSD.org> | 2001-08-21 22:55:20 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-08-21 22:55:20 +0000 |
commit | 6288c193137bf91669ae6f1f3e8fe9797510e549 (patch) | |
tree | 6b5ea370036bd40708c9ddd65a7b42155a6882ee /sys/kern/kern_shutdown.c | |
parent | f6cd2321ff50acefefd391b89e3f9e4fea4cd87f (diff) | |
download | FreeBSD-src-6288c193137bf91669ae6f1f3e8fe9797510e549.zip FreeBSD-src-6288c193137bf91669ae6f1f3e8fe9797510e549.tar.gz |
Allow one to restart from a panic in DDB by clearing the panicstr
variable to NULL. Note that since panic() is marked with __dead2, this
has somewhat unpredictable results at best.
Diffstat (limited to 'sys/kern/kern_shutdown.c')
-rw-r--r-- | sys/kern/kern_shutdown.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 91f45ab..a711cfb 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -566,12 +566,17 @@ panic(const char *fmt, ...) static char buf[256]; #ifdef SMP - /* Only 1 CPU can panic at a time */ - if (panic_cpu != PCPU_GET(cpuid) && - atomic_cmpset_int(&panic_cpu, NOCPU, PCPU_GET(cpuid)) == 0) { - for (;;) - ; /* nothing */ - } + /* + * We don't want multiple CPU's to panic at the same time, so we + * use panic_cpu as a simple spinlock. We have to keep checking + * panic_cpu if we are spinning in case the panic on the first + * CPU is canceled. + */ + if (panic_cpu != PCPU_GET(cpuid)) + while (atomic_cmpset_int(&panic_cpu, NOCPU, + PCPU_GET(cpuid)) == 0) + while (panic_cpu != NOCPU) + ; /* nothing */ #endif bootopt = RB_AUTOBOOT | RB_DUMP; @@ -597,6 +602,13 @@ panic(const char *fmt, ...) #if defined(DDB) if (debugger_on_panic) Debugger ("panic"); + /* See if the user aborted the panic, in which case we continue. */ + if (panicstr == NULL) { +#ifdef SMP + atomic_store_rel_int(&panic_cpu, NOCPU); +#endif + return; + } #endif boot(bootopt); } |