diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2019-03-23 05:30:17 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2019-03-23 05:30:17 +0000 |
commit | 805f6dc04087ae26b5b0db8f107a6685a3362df3 (patch) | |
tree | d83cd23c2f4e3a13edf8f632d97d8df3541c833b /sys | |
parent | 73bee3d6ff8da73a3fea6893578e505d13de0769 (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.c | 54 | ||||
-rw-r--r-- | sys/sys/mutex.h | 16 |
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 |