kern/99094: panic: sleeping thread (Sleeping thread ... owns a non-sleepable lock)

John Baldwin jhb at freebsd.org
Wed Jul 5 19:40:59 UTC 2006


The following reply was made to PR kern/99094; it has been noted by GNATS.

From: John Baldwin <jhb at freebsd.org>
To: Eirik =?iso-8859-15?q?=D8verby?= <ltning at anduin.net>
Cc: bug-followup at freebsd.org, des at freebsd.org
Subject: Re: kern/99094: panic: sleeping thread (Sleeping thread ... owns a non-sleepable lock)
Date: Wed, 5 Jul 2006 14:25:41 -0400

 On Saturday 01 July 2006 08:04, Eirik =D8verby wrote:
 > Hi again,
 >=20
 > I now have WITNESS and INVARIANTS in the kernel, and today it hung =20
 > again. It looks somewhat different than before, but I am fairly =20
 > certain it's the same error.
 >=20
 > Below you'll find the panic message, a bt, a ps, and then the output =20
 > of a "c", which is exactly the same as the first message except it's =20
 > not chopped off due to terminal size, and finally the panic resulting =20
 > from the boot() call.
 >=20
 > /Eirik
 >=20
 > malloc(M_WAITOK) of "1024", forcing M_NOWAIT with the following non-=20
 > sleepable locks held:
 > exclusive sleep mutex vm object (standard object) r =3D 0 =20
 > (0xffffff0018f3fe00) locked @ /usr/src/sys/compat/linprocfs/lin9
 > KDB: enter: witness_warn
 > [thread pid 77487 tid 100323 ]
 > Stopped at      kdb_enter+0x2f: nop
 > db>
 >=20
 >=20
 > db> bt
 > Tracing pid 77487 tid 100323 td 0xffffff00531794c0
 > kdb_enter() at kdb_enter+0x2f
 > witness_warn() at witness_warn+0x2e0
 > uma_zalloc_arg() at uma_zalloc_arg+0x1ee
 > malloc() at malloc+0xab
 > vn_fullpath() at vn_fullpath+0x56
 > linprocfs_doprocmaps() at linprocfs_doprocmaps+0x31e
 
 Well, the problem is in linprocfs.  It is trying to do some very expensive=
 =20
 things while holding a mutex.  Here's the code excerpt:
 
 		if (lobj) {
 			vp =3D lobj->handle;
 			VM_OBJECT_LOCK(lobj);
 			off =3D IDX_TO_OFF(lobj->size);
 			if (lobj->type =3D=3D OBJT_VNODE && lobj->handle) {
 				vn_fullpath(td, vp, &name, &freename);
 				VOP_GETATTR(vp, &vat, td->td_ucred, td);
 				ino =3D vat.va_fileid;
 			}
 			flags =3D obj->flags;
 			ref_count =3D obj->ref_count;
 			shadow_count =3D obj->shadow_count;
 			VM_OBJECT_UNLOCK(lobj);
 
 The VM_OBJECT_LOCK() is a mutex, and it can't really hold a mutex while=20
 calling things like vn_fullpath() and VOP_GETATTR() as those can block, etc=
 =2E =20
 It needs to probably be reordered to grab copies of the object fields under=
 =20
 the object lock, take a ref on the vnode (via vref) then do the vn_fullpath=
 ()=20
 and VOP_GETATTR() after dropping the vm object lock and finally do a vrele(=
 )=20
 to drop the vnode reference.  I'm cc'ing des@ as he's the linprocfs=20
 maintainer and should be able to help with this further.
 
 =2D-=20
 John Baldwin


More information about the freebsd-bugs mailing list