summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2017-03-16 01:04:30 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2017-03-16 01:04:30 +0000
commita6acb428e2f22d4740b7bbfca4bad1256fa2d4ac (patch)
treec3828146ab4b7d5af15730d72723e4a650903661
parent3ad363677eab284483e2586dcd92daceb2d036f2 (diff)
Notes
-rw-r--r--sys/kern/kern_mutex.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index b2f8bbdb96c9..b4b41b866ee5 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -152,6 +152,18 @@ SYSCTL_INT(_debug_mtx, OID_AUTO, delay_max, CTLFLAG_RW, &mtx_delay.max,
LOCK_DELAY_SYSINIT_DEFAULT(mtx_delay);
#endif
+static SYSCTL_NODE(_debug, OID_AUTO, mtx_spin, CTLFLAG_RD, NULL,
+ "mtx spin debugging");
+
+static struct lock_delay_config __read_mostly mtx_spin_delay;
+
+SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_base, CTLFLAG_RW,
+ &mtx_spin_delay.base, 0, "");
+SYSCTL_INT(_debug_mtx_spin, OID_AUTO, delay_max, CTLFLAG_RW,
+ &mtx_spin_delay.max, 0, "");
+
+LOCK_DELAY_SYSINIT_DEFAULT(mtx_spin_delay);
+
/*
* System-wide mutexes
*/
@@ -623,7 +635,7 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
const char *file, int line)
{
struct mtx *m;
- int i = 0;
+ struct lock_delay_arg lda;
#ifdef LOCK_PROFILING
int contested = 0;
uint64_t waittime = 0;
@@ -635,6 +647,7 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
if (SCHEDULER_STOPPED())
return;
+ lock_delay_arg_init(&lda, &mtx_spin_delay);
m = mtxlock2mtx(c);
if (LOCK_LOG_TEST(&m->lock_object, opts))
@@ -655,11 +668,13 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
/* Give interrupts a chance while we spin. */
spinlock_exit();
while (m->mtx_lock != MTX_UNOWNED) {
- if (i++ < 10000000) {
- cpu_spinwait();
+ if (lda.spin_cnt < 10000000) {
+ lock_delay(&lda);
continue;
}
- if (i < 60000000 || kdb_active || panicstr != NULL)
+ lda.spin_cnt++;
+ if (lda.spin_cnt < 60000000 || kdb_active ||
+ panicstr != NULL)
DELAY(1);
else
_mtx_lock_spin_failed(m);
@@ -690,7 +705,7 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
{
struct mtx *m;
uintptr_t tid;
- int i;
+ struct lock_delay_arg lda;
#ifdef LOCK_PROFILING
int contested = 0;
uint64_t waittime = 0;
@@ -699,7 +714,6 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
int64_t spin_time = 0;
#endif
- i = 0;
tid = (uintptr_t)curthread;
if (SCHEDULER_STOPPED()) {
@@ -712,6 +726,8 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
return;
}
+ lock_delay_arg_init(&lda, &mtx_spin_delay);
+
#ifdef KDTRACE_HOOKS
spin_time -= lockstat_nsecs(&td->td_lock->lock_object);
#endif
@@ -745,14 +761,17 @@ retry:
/* Give interrupts a chance while we spin. */
spinlock_exit();
while (m->mtx_lock != MTX_UNOWNED) {
- if (i++ < 10000000)
+ if (lda.spin_cnt < 10000000) {
+ lock_delay(&lda);
+ } else {
+ lda.spin_cnt++;
+ if (lda.spin_cnt < 60000000 ||
+ kdb_active || panicstr != NULL)
+ DELAY(1);
+ else
+ _mtx_lock_spin_failed(m);
cpu_spinwait();
- else if (i < 60000000 ||
- kdb_active || panicstr != NULL)
- DELAY(1);
- else
- _mtx_lock_spin_failed(m);
- cpu_spinwait();
+ }
if (m != td->td_lock)
goto retry;
}