Instead of having lfs muck directly about with vnode free lists,

introduce vrele2(), which allows to release vnodes the way lfs
sometimes wants it:
  + without calling inactive
  + inserting the vnode at the head of the freelist (this is a very
    questionable optimization that isn't even enabled by default,
    but I went along with the same semantics for now)
This commit is contained in:
pooka 2007-08-09 08:51:21 +00:00
parent dfeea3487b
commit 3de9f5d391
3 changed files with 41 additions and 58 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_subr.c,v 1.297 2007/08/06 17:09:11 pooka Exp $ */
/* $NetBSD: vfs_subr.c,v 1.298 2007/08/09 08:51:21 pooka Exp $ */
/*-
* Copyright (c) 1997, 1998, 2004, 2005 The NetBSD Foundation, Inc.
@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.297 2007/08/06 17:09:11 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.298 2007/08/09 08:51:21 pooka Exp $");
#include "opt_inet.h"
#include "opt_ddb.h"
@ -1129,8 +1129,8 @@ vput(struct vnode *vp)
* Vnode release.
* If count drops to zero, call inactive routine and return to freelist.
*/
void
vrele(struct vnode *vp)
static void
do_vrele(struct vnode *vp, int doinactive, int onhead)
{
struct lwp *l = curlwp; /* XXX */
@ -1154,18 +1154,41 @@ vrele(struct vnode *vp)
* Insert at tail of LRU list.
*/
simple_lock(&vnode_free_list_slock);
if (vp->v_holdcnt > 0)
if (vp->v_holdcnt > 0) {
TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
} else {
if (onhead)
TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
else
TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
}
simple_unlock(&vnode_free_list_slock);
if (vp->v_flag & VEXECMAP) {
uvmexp.execpages -= vp->v_uobj.uo_npages;
uvmexp.filepages += vp->v_uobj.uo_npages;
}
vp->v_flag &= ~(VTEXT|VEXECMAP|VWRITEMAP|VMAPPED);
if (doinactive) {
if (vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK) == 0)
VOP_INACTIVE(vp, l);
} else {
simple_unlock(&vp->v_interlock);
}
}
void
vrele(struct vnode *vp)
{
do_vrele(vp, 1, 0);
}
void
vrele2(struct vnode *vp, int onhead)
{
do_vrele(vp, 0, onhead);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: vnode.h,v 1.170 2007/06/29 23:30:32 rumble Exp $ */
/* $NetBSD: vnode.h,v 1.171 2007/08/09 08:51:21 pooka Exp $ */
/*
* Copyright (c) 1989, 1993
@ -533,6 +533,7 @@ void vprint(const char *, struct vnode *);
void vput(struct vnode *);
int vrecycle(struct vnode *, struct simplelock *, struct lwp *);
void vrele(struct vnode *);
void vrele2(struct vnode *, int);
int vtruncbuf(struct vnode *, daddr_t, int, int);
void vwakeup(struct buf *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_segment.c,v 1.203 2007/07/29 13:31:14 ad Exp $ */
/* $NetBSD: lfs_segment.c,v 1.204 2007/08/09 08:51:21 pooka Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.203 2007/07/29 13:31:14 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.204 2007/08/09 08:51:21 pooka Exp $");
#ifdef DEBUG
# define vndebug(vp, str) do { \
@ -2742,31 +2742,8 @@ lfs_vunref(struct vnode *vp)
return;
}
simple_lock(&vp->v_interlock);
#ifdef DIAGNOSTIC
if (vp->v_usecount <= 0) {
printf("lfs_vunref: inum is %llu\n", (unsigned long long)
VTOI(vp)->i_number);
printf("lfs_vunref: flags are 0x%lx\n", (u_long)vp->v_flag);
printf("lfs_vunref: usecount = %ld\n", (long)vp->v_usecount);
panic("lfs_vunref: v_usecount < 0");
}
#endif
vp->v_usecount--;
if (vp->v_usecount > 0) {
simple_unlock(&vp->v_interlock);
return;
}
/*
* insert at tail of LRU list
*/
simple_lock(&vnode_free_list_slock);
if (vp->v_holdcnt > 0)
TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
else
TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
simple_unlock(&vnode_free_list_slock);
simple_unlock(&vp->v_interlock);
/* does not call inactive */
vrele2(vp, 0);
}
/*
@ -2782,27 +2759,9 @@ lfs_vunref_head(struct vnode *vp)
{
ASSERT_SEGLOCK(VTOI(vp)->i_lfs);
simple_lock(&vp->v_interlock);
#ifdef DIAGNOSTIC
if (vp->v_usecount == 0) {
panic("lfs_vunref: v_usecount<0");
}
#endif
vp->v_usecount--;
if (vp->v_usecount > 0) {
simple_unlock(&vp->v_interlock);
return;
}
/*
* insert at head of LRU list
*/
simple_lock(&vnode_free_list_slock);
if (vp->v_holdcnt > 0)
TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
else
TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
simple_unlock(&vnode_free_list_slock);
simple_unlock(&vp->v_interlock);
/* does not call inactive, inserts non-held vnode at head of freelist */
vrele2(vp, 1);
}