Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Mar 2014 21:50:01 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        John Baldwin <jhb@freebsd.org>
Cc:        Alan Cox <alc@freebsd.org>, freebsd-current@freebsd.org, Andriy Gapon <avg@freebsd.org>, Bryan Drewery <bdrewery@freebsd.org>
Subject:   Re: panic: lockmgr still held [tmpfs] [vm_map_remove()->vdropl()] (r262186: Thu Feb 20)
Message-ID:  <20140305195001.GF24664@kib.kiev.ua>
In-Reply-To: <201403051421.04381.jhb@freebsd.org>
References:  <53109ACB.20102@FreeBSD.org> <5316F144.1000105@FreeBSD.org> <20140305110723.GB24664@kib.kiev.ua> <201403051421.04381.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--+TV/ighyc7Vd8/th
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Mar 05, 2014 at 02:21:04PM -0500, John Baldwin wrote:
> On Wednesday, March 05, 2014 6:07:23 am Konstantin Belousov wrote:
> > On Wed, Mar 05, 2014 at 11:41:24AM +0200, Andriy Gapon wrote:
> > > on 04/03/2014 18:45 John Baldwin said the following:
> > > > So I'm not sure how to fix this.  The crash is in this code in=20
> > > > vm_object_deallocate():
> > > >=20
> > > > 			if (object->type =3D=3D OBJT_SWAP &&
> > > > 			    (object->flags & OBJ_TMPFS) !=3D 0) {
> > > > 				vp =3D object->un_pager.swp.swp_tmpfs;
> > > > 				vhold(vp);
> > > > 				VM_OBJECT_WUNLOCK(object);
> > > > 				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
> > > > 				vdrop(vp);
> > > > 				VM_OBJECT_WLOCK(object);
> > > > 				if (object->type =3D=3D OBJT_DEAD ||
> > > > 				    object->ref_count !=3D 1) {
> > > > 					VM_OBJECT_WUNLOCK(object);
> > > > 					VOP_UNLOCK(vp, 0);
> > > > 					return;
> > > > 				}
> > > > 				if ((object->flags & OBJ_TMPFS) !=3D 0)
> > > > 					VOP_UNSET_TEXT(vp);
> > > > 				VOP_UNLOCK(vp, 0);
> > > > 			}
> > > >=20
> > > > The vdrop() is dropping the count to zero and trying to free the vn=
ode.  The=20
> > > > real problem I think is that swp_tmpfs doesn't have an implicit vho=
ld() on the=20
> > > > vnode, so in this case, the code is doing a vhold/vn_lock/vdrop of =
an already-
> > > > free vnode.  For OBJT_VNODE objects, the reference from the object =
back to the=20
> > > > vnode holds a vref() that gets released by a vput() in=20
> > > > vm_object_vndeallocate().
> > > >=20
> > > > One fix might be to chagne smp_tmpfs to hold a vhold reference.  Th=
is is=20
> > > > untested but might work (but I'm also not sure that this is the rig=
ht thing in=20
> > > > that I don't know what other effects it might have).
> > >=20
> > > I agree with your analysis, but I don't think that a filesystem holdi=
ng its own
> > > vnode is a good idea.  If I am not mistaken, that would prevent tmpfs=
 vnodes
> > > from going to free list.
> > > I'd rather try to modify vm_object_deallocate() code.  E.g. vdrop() c=
ould be
> > > called after VOP_UNLOCK().  Alternatively, the code could handle a do=
omed vnode
> > > in a different way.
> >=20
> > I agree with Andrey, it is just a bug to vdrop() before unlock.
> > Please try this.
>=20
> Ok, my only worry is in the case of Bryan's panic, the hold count on the =
vnode
> was already zero before vhold() was called, so is it possible that it is =
a stale
> pointer or is there some other implicit reference that prevents that?  If=
 it can't
> be stale, I think deferring the vdrop() is fine.

The object->un_pager.swp.swp_tmpfs is cleared under the object lock
before the vnode is reclaimed, i.e. long before the vnode can be freed.
swp_tmpfs should be kept in sync with the OBJ_TMPFS flag, so the
vhold() is safe while flag is set and object is locked.

--+TV/ighyc7Vd8/th
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)

iQIcBAEBAgAGBQJTF3/oAAoJEJDCuSvBvK1BT30P/2HQj2BS1x2SXpuy9fzHY/7T
qityHJT9VE7u16/Im0gtYopBT0N3W+HoLTuL8DYrBJoV/PDPYORB7frD2OA99Du7
q/dij85dqJbwowwnmA/nJFBBqRLb6ECFmCULBvS/1LHU695WeOVoZJ1N7xtGvceY
Kintppw2pGdJ2Ru7X9gX7Fm5/i3cxTuYaNdNBzqNZ//wHj8HOJ+Y8ucVuy0/vcug
npwUqs+QnFy12TSE/YUnaFLrYDGRGbkAPPfVxcik1sNxTq9p708FyKq76OA0MpPD
RwoGgBdVNwMY/K2SDsShFq7gQ6Pn86HdTAcLcEXBl8+/SLu7KVzeQcIlnORHQnVi
BNDllMwdYVks9CPy8BB8kqqZvEUfGC0TNaKPBT4nEqlQRCatTguxNRJudptZMrnE
LoTiVGnOYCx5EHVYPOiWoDimQTjrSUsq8zQ7wvp3NP9Niq979RsCnwBPpfx1DmfJ
PPJfhUDAFnN50W1pPbjHEzLr6tx+l24z9cFz3kd2kAb19FewR3Hh8m9ZoTT7O2Nv
IGJsaxPp+LX8JWQYO4+zkeDbAnpKvljzeTBWDmWVGPw4ZmHkkFYy8a237fjtun94
EQCFpXoYSUOurXWRRazm3eQw2BG+yg5PvebloulQAzmFjceAjncDUVL+393Wekdy
EzQfp8eU2V7PZEWLyARM
=6d1Z
-----END PGP SIGNATURE-----

--+TV/ighyc7Vd8/th--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140305195001.GF24664>