summaryrefslogtreecommitdiffstats
path: root/sys/uvm/uvm_vnode.c
diff options
context:
space:
mode:
authoroga <oga@openbsd.org>2009-04-05 18:11:03 +0000
committeroga <oga@openbsd.org>2009-04-05 18:11:03 +0000
commitfada7d6d5064b4975c80293680b3f0b11cc0aa39 (patch)
tree16eebcd92fa34b72f06244d2652508754deae67a /sys/uvm/uvm_vnode.c
parentregen; (diff)
downloadwireguard-openbsd-fada7d6d5064b4975c80293680b3f0b11cc0aa39.tar.xz
wireguard-openbsd-fada7d6d5064b4975c80293680b3f0b11cc0aa39.zip
In the unlikely even that we do the final unref on a uvm_vnode object
while there's io pending (async io makes that possible, but not often hit), then we'll be waiting for the pgo_releasepg hook to free the object when all of our pages disappear. However, uvn_releasepg, while it does everything else that unreferencing the object would do, it neglects to do the final vrele() on the vnode. So in this rare situation we'd end up with the vnode waiting around until it was forcibly recycled. Fix this by adding in the missing vrele(). ok thib@
Diffstat (limited to 'sys/uvm/uvm_vnode.c')
-rw-r--r--sys/uvm/uvm_vnode.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/uvm/uvm_vnode.c b/sys/uvm/uvm_vnode.c
index 4316c4eb908..138fb9dab22 100644
--- a/sys/uvm/uvm_vnode.c
+++ b/sys/uvm/uvm_vnode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_vnode.c,v 1.53 2009/03/20 15:19:04 oga Exp $ */
+/* $OpenBSD: uvm_vnode.c,v 1.54 2009/04/05 18:11:03 oga Exp $ */
/* $NetBSD: uvm_vnode.c,v 1.36 2000/11/24 20:34:01 chs Exp $ */
/*
@@ -650,6 +650,7 @@ boolean_t
uvn_releasepg(struct vm_page *pg, struct vm_page **nextpgp /* OUT */)
{
struct uvm_vnode *uvn = (struct uvm_vnode *) pg->uobject;
+ struct vnode *vp = (struct vnode *)uvn;
#ifdef DIAGNOSTIC
if ((pg->pg_flags & PG_RELEASED) == 0)
panic("uvn_releasepg: page not released!");
@@ -687,6 +688,7 @@ uvn_releasepg(struct vm_page *pg, struct vm_page **nextpgp /* OUT */)
uvn->u_flags = 0; /* DEAD! */
simple_unlock(&uvn->u_obj.vmobjlock);
+ vrele(vp);
return (FALSE);
}
}