From 7f20b0c529738b3a3a0e55d85cda378fecfe650e Mon Sep 17 00:00:00 2001 From: yamt Date: Wed, 14 Jan 2004 11:28:04 +0000 Subject: [PATCH] bump vnode hold count for page cache as well to resolve unfairness between page cache and traditional buffer cache. pointed by enami tsugutomo on current-users@. --- sys/kern/vfs_subr.c | 14 +++++--------- sys/sys/vnode.h | 45 ++++++++++++++++++++++++++++++++++++--------- sys/uvm/uvm_page.c | 34 ++++++++++++++++++++++++---------- 3 files changed, 65 insertions(+), 28 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index eed457c73f2d..5d0b51c7f8d0 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_subr.c,v 1.214 2004/01/10 17:16:38 hannken Exp $ */ +/* $NetBSD: vfs_subr.c,v 1.215 2004/01/14 11:28:05 yamt Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. @@ -78,7 +78,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.214 2004/01/10 17:16:38 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.215 2004/01/14 11:28:05 yamt Exp $"); #include "opt_inet.h" #include "opt_ddb.h" @@ -1364,7 +1364,7 @@ vrele(vp) * Page or buffer structure gets a reference. */ void -vhold(vp) +vholdl(vp) struct vnode *vp; { @@ -1381,7 +1381,6 @@ vhold(vp) * getnewvnode after removing it from a freelist to ensure * that we do not try to move it here. */ - simple_lock(&vp->v_interlock); if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb) && vp->v_holdcnt == 0 && vp->v_usecount == 0) { simple_lock(&vnode_free_list_slock); @@ -1390,20 +1389,18 @@ vhold(vp) simple_unlock(&vnode_free_list_slock); } vp->v_holdcnt++; - simple_unlock(&vp->v_interlock); } /* * Page or buffer structure frees a reference. */ void -holdrele(vp) +holdrelel(vp) struct vnode *vp; { - simple_lock(&vp->v_interlock); if (vp->v_holdcnt <= 0) - panic("holdrele: holdcnt vp %p", vp); + panic("holdrelel: holdcnt vp %p", vp); vp->v_holdcnt--; /* @@ -1427,7 +1424,6 @@ holdrele(vp) TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist); simple_unlock(&vnode_free_list_slock); } - simple_unlock(&vp->v_interlock); } /* diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 19f99a874baa..2de21224b9b6 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1,4 +1,4 @@ -/* $NetBSD: vnode.h,v 1.119 2004/01/10 17:16:38 hannken Exp $ */ +/* $NetBSD: vnode.h,v 1.120 2004/01/14 11:28:04 yamt Exp $ */ /* * Copyright (c) 1989, 1993 @@ -289,10 +289,13 @@ extern struct simplelock vnode_free_list_slock; #define ilstatic static #endif -ilstatic void holdrele(struct vnode *); -ilstatic void vhold(struct vnode *); +ilstatic void holdrelel(struct vnode *); +ilstatic void vholdl(struct vnode *); ilstatic void vref(struct vnode *); +static __inline void holdrele(struct vnode *) __attribute__((__unused__)); +static __inline void vhold(struct vnode *) __attribute__((__unused__)); + #ifdef DIAGNOSTIC #define VATTR_NULL(vap) vattr_null(vap) #else @@ -300,12 +303,13 @@ ilstatic void vref(struct vnode *); /* * decrease buf or page ref + * + * called with v_interlock held */ static __inline void -holdrele(struct vnode *vp) +holdrelel(struct vnode *vp) { - simple_lock(&vp->v_interlock); vp->v_holdcnt--; if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb) && vp->v_holdcnt == 0 && vp->v_usecount == 0) { @@ -314,17 +318,17 @@ holdrele(struct vnode *vp) TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist); simple_unlock(&vnode_free_list_slock); } - simple_unlock(&vp->v_interlock); } /* * increase buf or page ref + * + * called with v_interlock held */ static __inline void -vhold(struct vnode *vp) +vholdl(struct vnode *vp) { - simple_lock(&vp->v_interlock); if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb) && vp->v_holdcnt == 0 && vp->v_usecount == 0) { simple_lock(&vnode_free_list_slock); @@ -333,7 +337,6 @@ vhold(struct vnode *vp) simple_unlock(&vnode_free_list_slock); } vp->v_holdcnt++; - simple_unlock(&vp->v_interlock); } /* @@ -349,6 +352,30 @@ vref(struct vnode *vp) } #endif /* DIAGNOSTIC */ +/* + * decrease buf or page ref + */ +static __inline void +holdrele(struct vnode *vp) +{ + + simple_lock(&vp->v_interlock); + holdrelel(vp); + simple_unlock(&vp->v_interlock); +} + +/* + * increase buf or page ref + */ +static __inline void +vhold(struct vnode *vp) +{ + + simple_lock(&vp->v_interlock); + vholdl(vp); + simple_unlock(&vp->v_interlock); +} + #define NULLVP ((struct vnode *)NULL) #define VN_KNOTE(vp, b) KNOTE(&vp->v_klist, (b)) diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 5df9227463fc..29846f414cdc 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_page.c,v 1.93 2003/12/21 11:38:46 simonb Exp $ */ +/* $NetBSD: uvm_page.c,v 1.94 2004/01/14 11:28:05 yamt Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.93 2003/12/21 11:38:46 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.94 2004/01/14 11:28:05 yamt Exp $"); #include "opt_uvmhist.h" @@ -178,10 +178,17 @@ uvm_pageinsert(pg) TAILQ_INSERT_TAIL(buck, pg, hashq); simple_unlock(&uvm.hashlock); - if (UVM_OBJ_IS_VTEXT(uobj)) { - uvmexp.execpages++; - } else if (UVM_OBJ_IS_VNODE(uobj)) { - uvmexp.filepages++; + if (UVM_OBJ_IS_VNODE(uobj)) { + if (uobj->uo_npages == 0) { + struct vnode *vp = (struct vnode *)uobj; + + vholdl(vp); + } + if (UVM_OBJ_IS_VTEXT(uobj)) { + uvmexp.execpages++; + } else { + uvmexp.filepages++; + } } else if (UVM_OBJ_IS_AOBJ(uobj)) { uvmexp.anonpages++; } @@ -211,10 +218,17 @@ uvm_pageremove(pg) TAILQ_REMOVE(buck, pg, hashq); simple_unlock(&uvm.hashlock); - if (UVM_OBJ_IS_VTEXT(uobj)) { - uvmexp.execpages--; - } else if (UVM_OBJ_IS_VNODE(uobj)) { - uvmexp.filepages--; + if (UVM_OBJ_IS_VNODE(uobj)) { + if (uobj->uo_npages == 1) { + struct vnode *vp = (struct vnode *)uobj; + + holdrelel(vp); + } + if (UVM_OBJ_IS_VTEXT(uobj)) { + uvmexp.execpages--; + } else { + uvmexp.filepages--; + } } else if (UVM_OBJ_IS_AOBJ(uobj)) { uvmexp.anonpages--; }