panic: lockmgr still held [tmpfs] [vm_map_remove()->vdropl()] (r262186: Thu Feb 20)
Konstantin Belousov
kostikbel at gmail.com
Wed Mar 5 11:07:31 UTC 2014
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
> > vm_object_deallocate():
> >
> > if (object->type == OBJT_SWAP &&
> > (object->flags & OBJ_TMPFS) != 0) {
> > vp = 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 == OBJT_DEAD ||
> > object->ref_count != 1) {
> > VM_OBJECT_WUNLOCK(object);
> > VOP_UNLOCK(vp, 0);
> > return;
> > }
> > if ((object->flags & OBJ_TMPFS) != 0)
> > VOP_UNSET_TEXT(vp);
> > VOP_UNLOCK(vp, 0);
> > }
> >
> > The vdrop() is dropping the count to zero and trying to free the vnode. The
> > real problem I think is that swp_tmpfs doesn't have an implicit vhold() on the
> > 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
> > vnode holds a vref() that gets released by a vput() in
> > vm_object_vndeallocate().
> >
> > One fix might be to chagne smp_tmpfs to hold a vhold reference. This is
> > untested but might work (but I'm also not sure that this is the right thing in
> > that I don't know what other effects it might have).
>
> I agree with your analysis, but I don't think that a filesystem holding 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() could be
> called after VOP_UNLOCK(). Alternatively, the code could handle a doomed vnode
> in a different way.
I agree with Andrey, it is just a bug to vdrop() before unlock.
Please try this.
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 8683e2f..787b18b 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -536,17 +536,18 @@ vm_object_deallocate(vm_object_t object)
vhold(vp);
VM_OBJECT_WUNLOCK(object);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- vdrop(vp);
VM_OBJECT_WLOCK(object);
if (object->type == OBJT_DEAD ||
object->ref_count != 1) {
VM_OBJECT_WUNLOCK(object);
VOP_UNLOCK(vp, 0);
+ vdrop(vp);
return;
}
if ((object->flags & OBJ_TMPFS) != 0)
VOP_UNSET_TEXT(vp);
VOP_UNLOCK(vp, 0);
+ vdrop(vp);
}
if (object->shadow_count == 0 &&
object->handle == NULL &&
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-current/attachments/20140305/570535d4/attachment.sig>
More information about the freebsd-current
mailing list