summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r--sys/kern/vfs_subr.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 29dec8aa3aee..853bf765624d 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -122,6 +122,21 @@ SYSCTL_LONG(_debug, OID_AUTO, wantfreevnodes, CTLFLAG_RW, &wantfreevnodes, 0, ""
/* Number of vnodes in the free list. */
static u_long freevnodes = 0;
SYSCTL_LONG(_debug, OID_AUTO, freevnodes, CTLFLAG_RD, &freevnodes, 0, "");
+/* Number of vnode allocation. */
+static u_long vnodeallocs = 0;
+SYSCTL_LONG(_debug, OID_AUTO, vnodeallocs, CTLFLAG_RD, &vnodeallocs, 0, "");
+/* Period of vnode recycle from namecache in vnode allocation times. */
+static u_long vnoderecycleperiod = 1000;
+SYSCTL_LONG(_debug, OID_AUTO, vnoderecycleperiod, CTLFLAG_RW, &vnoderecycleperiod, 0, "");
+/* Minimum number of total vnodes required to invoke vnode recycle from namecache. */
+static u_long vnoderecyclemintotalvn = 2000;
+SYSCTL_LONG(_debug, OID_AUTO, vnoderecyclemintotalvn, CTLFLAG_RW, &vnoderecyclemintotalvn, 0, "");
+/* Minimum number of free vnodes required to invoke vnode recycle from namecache. */
+static u_long vnoderecycleminfreevn = 2000;
+SYSCTL_LONG(_debug, OID_AUTO, vnoderecycleminfreevn, CTLFLAG_RW, &vnoderecycleminfreevn, 0, "");
+/* Number of vnodes attempted to recycle at a time. */
+static u_long vnoderecyclenumber = 3000;
+SYSCTL_LONG(_debug, OID_AUTO, vnoderecyclenumber, CTLFLAG_RW, &vnoderecyclenumber, 0, "");
/*
* Various variables used for debugging the new implementation of
@@ -553,6 +568,7 @@ getnewvnode(tag, mp, vops, vpp)
if (vp == NULL || vp->v_usecount)
panic("getnewvnode: free vnode isn't");
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
+
/*
* Don't recycle if active in the namecache or
* if it still has cached pages or we cannot get
@@ -632,9 +648,19 @@ getnewvnode(tag, mp, vops, vpp)
*vpp = vp;
vp->v_usecount = 1;
vp->v_data = 0;
+
splx(s);
vfs_object_create(vp, p, p->p_ucred);
+
+ vnodeallocs++;
+ if (vnodeallocs % vnoderecycleperiod == 0 &&
+ freevnodes < vnoderecycleminfreevn &&
+ vnoderecyclemintotalvn < numvnodes) {
+ /* Recycle vnodes. */
+ cache_purgeleafdirs(vnoderecyclenumber);
+ }
+
return (0);
}