Date: Sun, 23 Sep 2001 14:29:00 -0700 (PDT) From: Matt Dillon <dillon@earth.backplane.com> To: Poul-Henning Kamp <phk@critter.freebsd.dk> Cc: David Greenman <dg@root.com>, Seigo Tanimura <tanimura@r.dl.itc.u-tokyo.ac.jp>, bright@wintelcom.net, hackers@FreeBSD.ORG Subject: cache purge cache for -current (Was Re: Conclusions on... cache_purgeleafdirs()) Message-ID: <200109232129.f8NLT0188769@earth.backplane.com> References: <1620.1001272770@critter>
next in thread | previous in thread | raw e-mail | index | archive | help
Here is the latest patch for -current. vmiodirenable is turned on by default, the cache purge code is enabled based on vmiodirenable, and I added a new sysctl called nameileafonly which defaults to ON (1). The old cache_purgeleafdirs() stuff is #if 0'd out. nameileafonly vmiodirenable action 1 1 (DEFAULT) purge leaf dirs on vnode reclaim 0 1 purge any dir on vnode reclaim 1 0 purge leaf dirs on vnode reclaim 0 0 do not purge dirs on vnode reclaim -1 0 puger any dir on vnode reclaim Index: sys/vnode.h =================================================================== RCS file: /home/ncvs/src/sys/sys/vnode.h,v retrieving revision 1.157 diff -u -r1.157 vnode.h --- sys/vnode.h 2001/09/13 22:52:42 1.157 +++ sys/vnode.h 2001/09/23 21:17:23 @@ -559,7 +559,7 @@ struct componentname *cnp)); void cache_purge __P((struct vnode *vp)); void cache_purgevfs __P((struct mount *mp)); -void cache_purgeleafdirs __P((int ndir)); +int cache_leaf_test __P((struct vnode *vp)); void cvtstat __P((struct stat *st, struct ostat *ost)); void cvtnstat __P((struct stat *sb, struct nstat *nsb)); int getnewvnode __P((enum vtagtype tag, Index: kern/vfs_bio.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v retrieving revision 1.288 diff -u -r1.288 vfs_bio.c --- kern/vfs_bio.c 2001/09/12 08:37:46 1.288 +++ kern/vfs_bio.c 2001/09/23 21:13:02 @@ -90,7 +90,7 @@ * but the code is intricate enough already. */ vm_page_t bogus_page; -int vmiodirenable = FALSE; +int vmiodirenable = TRUE; int runningbufspace; static vm_offset_t bogus_offset; Index: kern/vfs_cache.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_cache.c,v retrieving revision 1.61 diff -u -r1.61 vfs_cache.c --- kern/vfs_cache.c 2001/09/12 08:37:46 1.61 +++ kern/vfs_cache.c 2001/09/23 21:17:47 @@ -101,8 +101,10 @@ SYSCTL_ULONG(_debug, OID_AUTO, numcache, CTLFLAG_RD, &numcache, 0, ""); static u_long numcachehv; /* number of cache entries with vnodes held */ SYSCTL_ULONG(_debug, OID_AUTO, numcachehv, CTLFLAG_RD, &numcachehv, 0, ""); +#if 0 static u_long numcachepl; /* number of cache purge for leaf entries */ SYSCTL_ULONG(_debug, OID_AUTO, numcachepl, CTLFLAG_RD, &numcachepl, 0, ""); +#endif struct nchstats nchstats; /* cache effectiveness statistics */ static int doingcache = 1; /* 1 => enable the cache */ @@ -247,6 +249,31 @@ } /* + * cache_leaf_test() + * + * Test whether this (directory) vnode's namei cache entry contains + * subdirectories or not. Used to determine whether the directory is + * a leaf in the namei cache or not. Note: the directory may still + * contain files in the namei cache. + * + * Returns 0 if the directory is a leaf, -1 if it isn't. + */ +int +cache_leaf_test(struct vnode *vp) +{ + struct namecache *ncpc; + + for (ncpc = LIST_FIRST(&vp->v_cache_src); + ncpc != NULL; + ncpc = LIST_NEXT(ncpc, nc_src) + ) { + if (ncpc->nc_vp != NULL && ncpc->nc_vp->v_type == VDIR) + return(0); + } + return(-1); +} + +/* * Lookup an entry in the cache * * We don't do this if the segment name is long, simply so the cache @@ -499,6 +526,8 @@ } } +#if 0 + /* * Flush all dirctory entries with no child directories held in * the cache. @@ -554,6 +583,8 @@ } numcachepl++; } + +#endif /* * Perform canonical checks and cache lookup and pass on to filesystem Index: kern/vfs_subr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.319 diff -u -r1.319 vfs_subr.c --- kern/vfs_subr.c 2001/09/12 08:37:47 1.319 +++ kern/vfs_subr.c 2001/09/23 21:19:26 @@ -110,6 +110,8 @@ /* Number of vnodes in the free list. */ static u_long freevnodes = 0; SYSCTL_LONG(_debug, OID_AUTO, freevnodes, CTLFLAG_RD, &freevnodes, 0, ""); + +#if 0 /* Number of vnode allocation. */ static u_long vnodeallocs = 0; SYSCTL_LONG(_debug, OID_AUTO, vnodeallocs, CTLFLAG_RD, &vnodeallocs, 0, ""); @@ -125,6 +127,7 @@ /* Number of vnodes attempted to recycle at a time. */ static u_long vnoderecyclenumber = 3000; SYSCTL_LONG(_debug, OID_AUTO, vnoderecyclenumber, CTLFLAG_RW, &vnoderecyclenumber, 0, ""); +#endif /* * Various variables used for debugging the new implementation of @@ -142,6 +145,8 @@ /* Set to 0 for old insertion-sort based reassignbuf, 1 for modern method. */ static int reassignbufmethod = 1; SYSCTL_INT(_vfs, OID_AUTO, reassignbufmethod, CTLFLAG_RW, &reassignbufmethod, 0, ""); +static int nameileafonly = 1; +SYSCTL_INT(_vfs, OID_AUTO, nameileafonly, CTLFLAG_RW, &nameileafonly, 0, ""); #ifdef ENABLE_VFS_IOOPT /* See NOTES for a description of this setting. */ @@ -556,15 +561,46 @@ * Don't recycle if active in the namecache or * if it still has cached pages or we cannot get * its interlock. + * + * XXX the namei cache can hold onto vnodes too long, + * causing us to run out of MALLOC space. Instead, we + * should make path lookups requeue any vnodes on the free + * list. */ - if (LIST_FIRST(&vp->v_cache_src) != NULL || - (VOP_GETVOBJECT(vp, &object) == 0 && + if ((VOP_GETVOBJECT(vp, &object) == 0 && (object->resident_page_count || object->ref_count)) || !mtx_trylock(&vp->v_interlock)) { TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist); vp = NULL; continue; } + if (LIST_FIRST(&vp->v_cache_src)) { + /* + * If nameileafonly is set, do not throw + * away directory vnodes unless they are + * leaf nodes in the namecache. + * + * If nameileafonly is not set then throw-aways + * are based on vmiodirenable. If + * vmiodirenable is turned off we do not throw + * away directory vnodes active in the + * namecache. The (nameileafonly < 0) test + * is for further debugging only. + */ + if (nameileafonly > 0) { + if (cache_leaf_test(vp) == 0) { + mtx_unlock(&vp->v_interlock); + vp = NULL; + continue; + } + } else if (nameileafonly < 0 || + vmiodirenable == 0) { + mtx_unlock(&vp->v_interlock); + vp = NULL; + continue; + } + } + /* * Skip over it if its filesystem is being suspended. */ @@ -636,6 +672,7 @@ vfs_object_create(vp, td, td->td_proc->p_ucred); +#if 0 vnodeallocs++; if (vnodeallocs % vnoderecycleperiod == 0 && freevnodes < vnoderecycleminfreevn && @@ -643,6 +680,7 @@ /* Recycle vnodes. */ cache_purgeleafdirs(vnoderecyclenumber); } +#endif return (0); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200109232129.f8NLT0188769>