summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2019-03-23 05:30:17 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2019-03-23 05:30:17 +0000
commit805f6dc04087ae26b5b0db8f107a6685a3362df3 (patch)
treed83cd23c2f4e3a13edf8f632d97d8df3541c833b /sys
parent73bee3d6ff8da73a3fea6893578e505d13de0769 (diff)
Add a simple spinning mutex for ddb. Unlike mutex(9), this lock keeps
on spinning even if `db_active' or `panicstr' has been set. The new mutex also disables IPIs in the critical section. OK mpi@ patrick@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_lock.c54
-rw-r--r--sys/sys/mutex.h16
2 files changed, 68 insertions, 2 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 7b91ac1d9e4..f83bf5cf2ef 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_lock.c,v 1.67 2019/02/25 04:50:25 visa Exp $ */
+/* $OpenBSD: kern_lock.c,v 1.68 2019/03/23 05:30:16 visa Exp $ */
/*
* Copyright (c) 2017 Visa Hankala
@@ -367,6 +367,58 @@ __mtx_leave(struct mutex *mtx)
if (mtx->mtx_wantipl != IPL_NONE)
splx(s);
}
+
+#ifdef DDB
+void
+db_mtx_enter(struct db_mutex *mtx)
+{
+ struct cpu_info *ci = curcpu(), *owner;
+ unsigned long s;
+
+#ifdef DIAGNOSTIC
+ if (__predict_false(mtx->mtx_owner == ci))
+ panic("%s: mtx %p: locking against myself", __func__, mtx);
+#endif
+
+ s = intr_disable();
+
+ for (;;) {
+ owner = atomic_cas_ptr(&mtx->mtx_owner, NULL, ci);
+ if (owner == NULL)
+ break;
+ CPU_BUSY_CYCLE();
+ }
+ membar_enter_after_atomic();
+
+ mtx->mtx_intr_state = s;
+
+#ifdef DIAGNOSTIC
+ ci->ci_mutex_level++;
+#endif
+}
+
+void
+db_mtx_leave(struct db_mutex *mtx)
+{
+#ifdef DIAGNOSTIC
+ struct cpu_info *ci = curcpu();
+#endif
+ unsigned long s;
+
+#ifdef DIAGNOSTIC
+ if (__predict_false(mtx->mtx_owner != ci))
+ panic("%s: mtx %p: not owned by this CPU", __func__, mtx);
+ ci->ci_mutex_level--;
+#endif
+
+ s = mtx->mtx_intr_state;
+#ifdef MULTIPROCESSOR
+ membar_exit();
+#endif
+ mtx->mtx_owner = NULL;
+ intr_restore(s);
+}
+#endif /* DDB */
#endif /* __USE_MI_MUTEX */
#ifdef WITNESS
diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h
index c926647cac0..2bc0066e7e0 100644
--- a/sys/sys/mutex.h
+++ b/sys/sys/mutex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mutex.h,v 1.16 2019/01/23 22:39:47 tedu Exp $ */
+/* $OpenBSD: mutex.h,v 1.17 2019/03/23 05:30:16 visa Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
@@ -158,4 +158,18 @@ void _mtx_leave(struct mutex *, const char *, int);
#endif /* WITNESS */
+#if defined(_KERNEL) && defined(DDB)
+
+struct db_mutex {
+ struct cpu_info *mtx_owner;
+ unsigned long mtx_intr_state;
+};
+
+#define DB_MUTEX_INITIALIZER { NULL, 0 }
+
+void db_mtx_enter(struct db_mutex *);
+void db_mtx_leave(struct db_mutex *);
+
+#endif /* _KERNEL && DDB */
+
#endif