Index: sys/lock.h =================================================================== RCS file: /private/FreeBSD/src/sys/sys/lock.h,v retrieving revision 1.50 diff -u -p -r1.50 lock.h --- sys/lock.h 28 Jan 2004 20:39:57 -0000 1.50 +++ sys/lock.h 8 Apr 2004 20:43:47 -0000 @@ -78,6 +78,7 @@ struct lock_class { #define LOP_QUIET 0x00000002 /* Don't log locking operations. */ #define LOP_TRYLOCK 0x00000004 /* Don't check lock order. */ #define LOP_EXCLUSIVE 0x00000008 /* Exclusive lock. */ +#define LOP_RECURSE 0x00000010 /* Explicit allow for recursion. */ /* Flags passed to witness_assert. */ #define LA_UNLOCKED 0x00000000 /* Lock is unlocked. */ Index: sys/mutex.h =================================================================== RCS file: /private/FreeBSD/src/sys/sys/mutex.h,v retrieving revision 1.70 diff -u -p -r1.70 mutex.h --- sys/mutex.h 28 Mar 2004 23:12:19 -0000 1.70 +++ sys/mutex.h 8 Apr 2004 20:45:40 -0000 @@ -231,9 +231,11 @@ void _mtx_assert(struct mtx *m, int what * mtx_recursed(m) returns non-zero if the lock `m' is presently recursed. */ #define mtx_lock(m) mtx_lock_flags((m), 0) +#define mtx_lock_recurse(m) mtx_lock_flags((m), LOP_RECURSE) #define mtx_lock_spin(m) mtx_lock_spin_flags((m), 0) #define mtx_trylock(m) mtx_trylock_flags((m), 0) #define mtx_unlock(m) mtx_unlock_flags((m), 0) +#define mtx_unlock_recurse(m) mtx_unlock_flags((m), LOP_RECURSE) #define mtx_unlock_spin(m) mtx_unlock_spin_flags((m), 0) struct mtx_pool; Index: kern/kern_mutex.c =================================================================== RCS file: /private/FreeBSD/src/sys/kern/kern_mutex.c,v retrieving revision 1.137 diff -u -p -r1.137 kern_mutex.c --- kern/kern_mutex.c 28 Jan 2004 22:11:53 -0000 1.137 +++ kern/kern_mutex.c 8 Apr 2004 20:52:00 -0000 @@ -431,7 +431,8 @@ _mtx_lock_sleep(struct mtx *m, int opts, #endif if (mtx_owned(m)) { - KASSERT((m->mtx_object.lo_flags & LO_RECURSABLE) != 0, + KASSERT((m->mtx_object.lo_flags & LO_RECURSABLE) != 0 || + (opts & LOP_RECURSE) != 0, ("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n", m->mtx_object.lo_name, file, line)); m->mtx_recurse++; @@ -619,6 +620,10 @@ _mtx_unlock_sleep(struct mtx *m, int opt struct thread *td, *td1; if (mtx_recursed(m)) { + KASSERT((m->mtx_object.lo_flags & LO_RECURSABLE) != 0 || + (opts & LOP_RECURSE) != 0, + ("_mtx_unlock_sleep: expected mtx_unlock_recurse on mutex %s @ %s:%d\n", + m->mtx_object.lo_name, file, line)); if (--(m->mtx_recurse) == 0) atomic_clear_ptr(&m->mtx_lock, MTX_RECURSED); if (LOCK_LOG_TEST(&m->mtx_object, opts))