Add vrele_async routine which asynchronously release vnodes in different contex

and in some time in the future.

Ok: ad@.
This commit is contained in:
haad 2010-02-11 23:16:35 +00:00
parent a23681588b
commit aa8090778a
3 changed files with 34 additions and 5 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: vnode.9,v 1.44 2010/01/08 13:15:46 pooka Exp $
.\" $NetBSD: vnode.9,v 1.45 2010/02/11 23:16:35 haad Exp $
.\"
.\" Copyright (c) 2001, 2005, 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -34,6 +34,7 @@
.Nm vnode ,
.Nm vref ,
.Nm vrele ,
.Nm vrele_async ,
.Nm vget ,
.Nm vput ,
.Nm vhold ,
@ -62,6 +63,8 @@
.Fn vref "struct vnode *vp"
.Ft void
.Fn vrele "struct vnode *vp"
.Ft void
.Fn vrele_async "struct vnode *vp"
.Ft int
.Fn vget "struct vnode *vp" "int lockflag"
.Ft void
@ -246,6 +249,7 @@ kernel to the vnode.
This count is maintained by
.Fn vref ,
.Fn vrele ,
.Fn vrele_async ,
and
.Fn vput .
The second is the number of active references within the kernel to the
@ -531,6 +535,8 @@ and
.Em v_holdcnt
are zero, the vnode is placed on the freelist.
.It Fn vget "vp" "lockflags"
.It Fn vrele_async "vp"
Will asychronously release vnode in different context than caller, sometime in future.
Reclaim vnode
.Fa vp
from the freelist, increment its reference count and lock it.

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_subr.c,v 1.397 2010/01/15 19:28:26 bouyer Exp $ */
/* $NetBSD: vfs_subr.c,v 1.398 2010/02/11 23:16:35 haad Exp $ */
/*-
* Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.397 2010/01/15 19:28:26 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.398 2010/02/11 23:16:35 haad Exp $");
#include "opt_ddb.h"
#include "opt_compat_netbsd.h"
@ -1424,8 +1424,12 @@ vrelel(vnode_t *vp, int flags)
/*
* XXX This ugly block can be largely eliminated if
* locking is pushed down into the file systems.
*
* Defer vnode release to vrele_thread if caller
* requests it explicitly.
*/
if (curlwp == uvm.pagedaemon_lwp) {
if ((curlwp == uvm.pagedaemon_lwp) ||
(flags & VRELEL_ASYNC_RELE) != 0) {
/* The pagedaemon can't wait around; defer. */
defer = true;
} else if (curlwp == vrele_lwp) {
@ -1599,6 +1603,23 @@ vrele(vnode_t *vp)
vrelel(vp, 0);
}
/*
* Asynchronous vnode release, vnode is released in different context.
*/
void
vrele_async(vnode_t *vp)
{
KASSERT((vp->v_iflag & VI_MARKER) == 0);
if ((vp->v_iflag & VI_INACTNOW) == 0 && vtryrele(vp)) {
return;
}
mutex_enter(&vp->v_interlock);
vrelel(vp, VRELEL_ASYNC_RELE);
}
static void
vrele_thread(void *cookie)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: vnode.h,v 1.213 2010/01/27 15:34:08 uebayasi Exp $ */
/* $NetBSD: vnode.h,v 1.214 2010/02/11 23:16:35 haad Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -601,6 +601,7 @@ void vprint(const char *, struct vnode *);
void vput(struct vnode *);
int vrecycle(struct vnode *, kmutex_t *, struct lwp *);
void vrele(struct vnode *);
void vrele_async(struct vnode *);
int vtruncbuf(struct vnode *, daddr_t, bool, int);
void vwakeup(struct buf *);
void vwait(struct vnode *, int);
@ -609,6 +610,7 @@ void vrevoke(struct vnode *);
void vrelel(struct vnode *, int);
#define VRELEL_NOINACTIVE 0x01
#define VRELEL_ONHEAD 0x02
#define VRELEL_ASYNC_RELE 0x03
struct vnode *
vnalloc(struct mount *);
void vnfree(struct vnode *);