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>
