summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_shutdown.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-04-17 04:18:08 +0000
committerjhb <jhb@FreeBSD.org>2001-04-17 04:18:08 +0000
commit82848b046f3ceba1d796ce044c2df7fc6751b0a8 (patch)
treeb24d73d402dafba57539f1a615d5b5e5fb09b9e6 /sys/kern/kern_shutdown.c
parentd16229755ce4eb76c4fc82062166cc254736985c (diff)
downloadFreeBSD-src-82848b046f3ceba1d796ce044c2df7fc6751b0a8.zip
FreeBSD-src-82848b046f3ceba1d796ce044c2df7fc6751b0a8.tar.gz
Blow away the panic mutex in favor of using a single atomic_cmpset() on a
panic_cpu shared variable. I used a simple atomic operation here instead of a spin lock as it seemed to be excessive overhead. Also, this can avoid recursive panics if, for example, witness is broken.
Diffstat (limited to 'sys/kern/kern_shutdown.c')
-rw-r--r--sys/kern/kern_shutdown.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index ad79fdc..55c4ba4 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -548,6 +548,10 @@ dumpstatus(vm_offset_t addr, long count)
return 0;
}
+#ifdef SMP
+static u_int panic_cpu = NOCPU;
+#endif
+
/*
* Panic is called on unresolvable fatal errors. It prints "panic: mesg",
* and then reboots. If we are called twice, then we avoid trying to sync
@@ -562,7 +566,11 @@ panic(const char *fmt, ...)
#ifdef SMP
/* Only 1 CPU can panic at a time */
- mtx_lock(&panic_mtx);
+ if (panic_cpu != PCPU_GET(cpuid) &&
+ atomic_cmpset_int(&panic_cpu, NOCPU, PCPU_GET(cpuid)) == 0) {
+ for (;;)
+ ; /* nothing */
+ }
#endif
bootopt = RB_AUTOBOOT | RB_DUMP;
OpenPOWER on IntegriCloud