diff options
Diffstat (limited to 'sys/kern/vfs_subr.c')
| -rw-r--r-- | sys/kern/vfs_subr.c | 26 |
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); } |
