svn commit: r330418 - head/sys/kern
Mateusz Guzik
mjg at FreeBSD.org
Sun Mar 4 22:01:24 UTC 2018
Author: mjg
Date: Sun Mar 4 22:01:23 2018
New Revision: 330418
URL: https://svnweb.freebsd.org/changeset/base/330418
Log:
mtx: tidy up recursion handling in thread lock
Normally after grabbing the lock it has to be verified we got the right one
to begin with. However, if we are recursing, it must not change thus the
check can be avoided. In particular this avoids a lock read for non-recursing
case which found out the lock was changed.
While here avoid an irq trip of this happens.
Tested by: pho (previous version)
Modified:
head/sys/kern/kern_mutex.c
Modified: head/sys/kern/kern_mutex.c
==============================================================================
--- head/sys/kern/kern_mutex.c Sun Mar 4 21:58:55 2018 (r330417)
+++ head/sys/kern/kern_mutex.c Sun Mar 4 22:01:23 2018 (r330418)
@@ -829,10 +829,8 @@ _thread_lock(struct thread *td)
WITNESS_LOCK(&m->lock_object, LOP_EXCLUSIVE, file, line);
return;
}
- if (m->mtx_recurse != 0)
- m->mtx_recurse--;
- else
- _mtx_release_lock_quick(m);
+ MPASS(m->mtx_recurse == 0);
+ _mtx_release_lock_quick(m);
slowpath_unlocked:
spinlock_exit();
slowpath_noirq:
@@ -886,9 +884,10 @@ thread_lock_flags_(struct thread *td, int opts, const
if (__predict_false(doing_lockprof))
spin_time -= lockstat_nsecs(&td->td_lock->lock_object);
#endif
+ spinlock_enter();
+
for (;;) {
retry:
- spinlock_enter();
m = td->td_lock;
thread_lock_validate(m, opts, file, line);
v = MTX_READ_VALUE(m);
@@ -900,6 +899,7 @@ retry:
}
if (v == tid) {
m->mtx_recurse++;
+ MPASS(m == td->td_lock);
break;
}
lock_profile_obtain_lock_failed(&m->lock_object,
@@ -912,15 +912,18 @@ retry:
} else {
_mtx_lock_indefinite_check(m, &lda);
}
- if (m != td->td_lock)
+ if (m != td->td_lock) {
+ spinlock_enter();
goto retry;
+ }
v = MTX_READ_VALUE(m);
} while (v != MTX_UNOWNED);
spinlock_enter();
}
if (m == td->td_lock)
break;
- __mtx_unlock_spin(m); /* does spinlock_exit() */
+ MPASS(m->mtx_recurse == 0);
+ _mtx_release_lock_quick(m);
}
LOCK_LOG_LOCK("LOCK", &m->lock_object, opts, m->mtx_recurse, file,
line);
More information about the svn-src-all
mailing list