summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_shutdown.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-08-21 22:55:20 +0000
committerjhb <jhb@FreeBSD.org>2001-08-21 22:55:20 +0000
commit6288c193137bf91669ae6f1f3e8fe9797510e549 (patch)
tree6b5ea370036bd40708c9ddd65a7b42155a6882ee /sys/kern/kern_shutdown.c
parentf6cd2321ff50acefefd391b89e3f9e4fea4cd87f (diff)
downloadFreeBSD-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.c24
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);
}
OpenPOWER on IntegriCloud