Date: Mon, 11 Oct 2004 14:57:17 -0400 From: John Baldwin <jhb@FreeBSD.org> To: freebsd-hackers@FreeBSD.org Cc: damien.bergamini@free.fr Subject: Re: msleep(9) and recursed mutex Message-ID: <200410111457.17529.jhb@FreeBSD.org> In-Reply-To: <1097500245.416a86556c692@imp1-q.free.fr> References: <1097500245.416a86556c692@imp1-q.free.fr>
next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 11 October 2004 09:10 am, damien.bergamini@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@FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200410111457.17529.jhb>