From owner-freebsd-current@FreeBSD.ORG Wed Mar 5 09:42:58 2014 Return-Path: Delivered-To: freebsd-current@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 355B9B06; Wed, 5 Mar 2014 09:42:58 +0000 (UTC) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id AF3981C2; Wed, 5 Mar 2014 09:42:56 +0000 (UTC) Received: from porto.starpoint.kiev.ua (porto-e.starpoint.kiev.ua [212.40.38.100]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id LAA29269; Wed, 05 Mar 2014 11:42:46 +0200 (EET) (envelope-from avg@FreeBSD.org) Received: from localhost ([127.0.0.1]) by porto.starpoint.kiev.ua with esmtp (Exim 4.34 (FreeBSD)) id 1WL8Ld-0006Vj-V6; Wed, 05 Mar 2014 11:42:45 +0200 Message-ID: <5316F144.1000105@FreeBSD.org> Date: Wed, 05 Mar 2014 11:41:24 +0200 From: Andriy Gapon User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: John Baldwin , Bryan Drewery , Konstantin Belousov , Alan Cox Subject: Re: panic: lockmgr still held [tmpfs] [vm_map_remove()->vdropl()] (r262186: Thu Feb 20) References: <53109ACB.20102@FreeBSD.org> <201403031306.59405.jhb@freebsd.org> <53153F43.6010506@FreeBSD.org> <201403041145.48425.jhb@freebsd.org> In-Reply-To: <201403041145.48425.jhb@freebsd.org> X-Enigmail-Version: 1.6 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-current@FreeBSD.org X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Mar 2014 09:42:58 -0000 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. -- Andriy Gapon