svn commit: r254139 - in head: share/man/man9 sys/kern
Attilio Rao
attilio at FreeBSD.org
Fri Aug 9 11:24:30 UTC 2013
Author: attilio
Date: Fri Aug 9 11:24:29 2013
New Revision: 254139
URL: http://svnweb.freebsd.org/changeset/base/254139
Log:
Give mutex(9) the ability to recurse on a per-instance basis.
Now the MTX_RECURSE flag can be passed to the mtx_*_flag() calls.
This helps in cases we want to narrow down to specific calls the
possibility to recurse for some locks.
Sponsored by: EMC / Isilon storage division
Reviewed by: jeff, alc
Tested by: pho
Modified:
head/share/man/man9/mutex.9
head/sys/kern/kern_mutex.c
Modified: head/share/man/man9/mutex.9
==============================================================================
--- head/share/man/man9/mutex.9 Fri Aug 9 11:11:11 2013 (r254138)
+++ head/share/man/man9/mutex.9 Fri Aug 9 11:24:29 2013 (r254139)
@@ -225,8 +225,10 @@ or
lock, respectively, and also accept a
.Fa flags
argument.
-In both cases, the only flag presently available for lock acquires is
-.Dv MTX_QUIET .
+In both cases, the only flags presently available for lock acquires are
+.Dv MTX_QUIET
+and
+.Dv MTX_RECURSE .
If the
.Dv MTX_QUIET
bit is turned on in the
@@ -235,6 +237,12 @@ argument, then if
.Dv KTR_LOCK
tracing is being done,
it will be silenced during the lock acquire.
+If the
+.Dv MTX_RECURSE
+bit is turned on in the
+.Fa flags
+argument, then the mutex can be acquired recursively.
+.Pp
.Pp
The
.Fn mtx_trylock
Modified: head/sys/kern/kern_mutex.c
==============================================================================
--- head/sys/kern/kern_mutex.c Fri Aug 9 11:11:11 2013 (r254138)
+++ head/sys/kern/kern_mutex.c Fri Aug 9 11:24:29 2013 (r254139)
@@ -218,13 +218,14 @@ __mtx_lock_flags(volatile uintptr_t *c,
KASSERT(LOCK_CLASS(&m->lock_object) == &lock_class_mtx_sleep,
("mtx_lock() of spin mutex %s @ %s:%d", m->lock_object.lo_name,
file, line));
- WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
- file, line, NULL);
+ WITNESS_CHECKORDER(&m->lock_object, (opts & ~MTX_RECURSE) |
+ LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL);
__mtx_lock(m, curthread, opts, file, line);
LOCK_LOG_LOCK("LOCK", &m->lock_object, opts, m->mtx_recurse, file,
line);
- WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE, file, line);
+ WITNESS_LOCK(&m->lock_object, (opts & ~MTX_RECURSE) | LOP_EXCLUSIVE,
+ file, line);
curthread->td_locks++;
}
@@ -271,9 +272,11 @@ __mtx_lock_spin_flags(volatile uintptr_t
("mtx_lock_spin() of sleep mutex %s @ %s:%d",
m->lock_object.lo_name, file, line));
if (mtx_owned(m))
- KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0,
+ KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
+ (opts & MTX_RECURSE) != 0,
("mtx_lock_spin: recursed on non-recursive mutex %s @ %s:%d\n",
m->lock_object.lo_name, file, line));
+ opts &= ~MTX_RECURSE;
WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
file, line, NULL);
__mtx_lock_spin(m, curthread, opts, file, line);
@@ -335,12 +338,14 @@ _mtx_trylock_flags_(volatile uintptr_t *
("mtx_trylock() of spin mutex %s @ %s:%d", m->lock_object.lo_name,
file, line));
- if (mtx_owned(m) && (m->lock_object.lo_flags & LO_RECURSABLE) != 0) {
+ if (mtx_owned(m) && ((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
+ (opts & MTX_RECURSE) != 0)) {
m->mtx_recurse++;
atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
rval = 1;
} else
rval = _mtx_obtain_lock(m, (uintptr_t)curthread);
+ opts &= ~MTX_RECURSE;
LOCK_LOG_TRY("LOCK", &m->lock_object, opts, rval, file, line);
if (rval) {
@@ -391,15 +396,18 @@ __mtx_lock_sleep(volatile uintptr_t *c,
m = mtxlock2mtx(c);
if (mtx_owned(m)) {
- KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0,
+ KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
+ (opts & MTX_RECURSE) != 0,
("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n",
m->lock_object.lo_name, file, line));
+ opts &= ~MTX_RECURSE;
m->mtx_recurse++;
atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
if (LOCK_LOG_TEST(&m->lock_object, opts))
CTR1(KTR_LOCK, "_mtx_lock_sleep: %p recursing", m);
return;
}
+ opts &= ~MTX_RECURSE;
#ifdef HWPMC_HOOKS
PMC_SOFT_CALL( , , lock, failed);
More information about the svn-src-head
mailing list