msleep(9) and recursed mutex
John Baldwin
jhb at FreeBSD.org
Mon Oct 11 14:27:24 PDT 2004
On Monday 11 October 2004 09:10 am, damien.bergamini at free.fr wrote:
> msleep(9) behaves strangely with recursed mutexes.
> In the attached code, calling foo_f() will make the kernel hang for
> two seconds.
> It seems like msleep does not release the mtx mutex completely but
> simply decrement its reference count by one. When calling msleep, the
> mtx mutex is still held which prevent the interrupt from happening.
> msleep will then return error code EWOULDBLOCK after two seconds.
> If I remove calls to mtx_lock/unlock from function foo_g(), it works
> without problem but this is not a solution since foo_g() can be
> called outside of function foo_f().
> Of course, the mtx mutex was created with the MTX_RECURSE flag set.
This is a feature. If you had INVARIANTS on you would get a panic here:
if (mtx != NULL) {
mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED);
WITNESS_SAVE(&mtx->mtx_object, mtx);
mtx_unlock(mtx);
}
When developing kernel code it is highly recommended that you run with
INVARIANTS and INVARIANT_SUPPORT turned on.
You should probably have your foo_g() function assert that the lock is held
and fix all the callers. Either that or add a wrapper around foo_g() for the
callers that don't call with the mutex locked.
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the freebsd-hackers
mailing list