svn commit: r366988 - head/sys/kern

Mateusz Guzik mjg at FreeBSD.org
Sat Oct 24 01:14:53 UTC 2020


Author: mjg
Date: Sat Oct 24 01:14:52 2020
New Revision: 366988
URL: https://svnweb.freebsd.org/changeset/base/366988

Log:
  cache: batch updates to numcache in case of mass removal

Modified:
  head/sys/kern/vfs_cache.c

Modified: head/sys/kern/vfs_cache.c
==============================================================================
--- head/sys/kern/vfs_cache.c	Sat Oct 24 01:14:17 2020	(r366987)
+++ head/sys/kern/vfs_cache.c	Sat Oct 24 01:14:52 2020	(r366988)
@@ -110,6 +110,7 @@ SDT_PROBE_DEFINE2(vfs, namecache, removecnp, hit, "str
 SDT_PROBE_DEFINE2(vfs, namecache, removecnp, miss, "struct vnode *",
     "struct componentname *");
 SDT_PROBE_DEFINE1(vfs, namecache, purge, done, "struct vnode *");
+SDT_PROBE_DEFINE1(vfs, namecache, purge, batch, "int");
 SDT_PROBE_DEFINE1(vfs, namecache, purge_negative, done, "struct vnode *");
 SDT_PROBE_DEFINE1(vfs, namecache, purgevfs, done, "struct mount *");
 SDT_PROBE_DEFINE3(vfs, namecache, zap, done, "struct vnode *", "char *",
@@ -166,6 +167,8 @@ struct	namecache_ts {
 	struct namecache nc_nc;
 };
 
+TAILQ_HEAD(cache_freebatch, namecache);
+
 /*
  * At least mips n32 performs 64-bit accesses to timespec as found
  * in namecache_ts and requires them to be aligned. Since others
@@ -626,6 +629,27 @@ cache_free(struct namecache *ncp)
 	atomic_subtract_long(&numcache, 1);
 }
 
+static void
+cache_free_batch(struct cache_freebatch *batch)
+{
+	struct namecache *ncp, *nnp;
+	int i;
+
+	i = 0;
+	if (TAILQ_EMPTY(batch))
+		goto out;
+	TAILQ_FOREACH_SAFE(ncp, batch, nc_dst, nnp) {
+		if ((ncp->nc_flag & NCF_DVDROP) != 0) {
+			cache_drop_vnode(ncp->nc_dvp);
+		}
+		cache_free_uma(ncp);
+		i++;
+	}
+	atomic_subtract_long(&numcache, i);
+out:
+	SDT_PROBE1(vfs, namecache, purge, batch, i);
+}
+
 /*
  * TODO: With the value stored we can do better than computing the hash based
  * on the address. The choice of FNV should also be revisited.
@@ -2524,11 +2548,11 @@ cache_changesize(u_long newmaxvnodes)
 static void
 cache_purge_impl(struct vnode *vp)
 {
-	TAILQ_HEAD(, namecache) ncps;
-	struct namecache *ncp, *nnp;
+	struct cache_freebatch batch;
+	struct namecache *ncp;
 	struct mtx *vlp, *vlp2;
 
-	TAILQ_INIT(&ncps);
+	TAILQ_INIT(&batch);
 	vlp = VP2VNODELOCK(vp);
 	vlp2 = NULL;
 	mtx_lock(vlp);
@@ -2537,13 +2561,13 @@ retry:
 		ncp = LIST_FIRST(&vp->v_cache_src);
 		if (!cache_zap_locked_vnode_kl2(ncp, vp, &vlp2))
 			goto retry;
-		TAILQ_INSERT_TAIL(&ncps, ncp, nc_dst);
+		TAILQ_INSERT_TAIL(&batch, ncp, nc_dst);
 	}
 	while (!TAILQ_EMPTY(&vp->v_cache_dst)) {
 		ncp = TAILQ_FIRST(&vp->v_cache_dst);
 		if (!cache_zap_locked_vnode_kl2(ncp, vp, &vlp2))
 			goto retry;
-		TAILQ_INSERT_TAIL(&ncps, ncp, nc_dst);
+		TAILQ_INSERT_TAIL(&batch, ncp, nc_dst);
 	}
 	ncp = vp->v_cache_dd;
 	if (ncp != NULL) {
@@ -2551,15 +2575,13 @@ retry:
 		   ("lost dotdot link"));
 		if (!cache_zap_locked_vnode_kl2(ncp, vp, &vlp2))
 			goto retry;
-		TAILQ_INSERT_TAIL(&ncps, ncp, nc_dst);
+		TAILQ_INSERT_TAIL(&batch, ncp, nc_dst);
 	}
 	KASSERT(vp->v_cache_dd == NULL, ("incomplete purge"));
 	mtx_unlock(vlp);
 	if (vlp2 != NULL)
 		mtx_unlock(vlp2);
-	TAILQ_FOREACH_SAFE(ncp, &ncps, nc_dst, nnp) {
-		cache_free(ncp);
-	}
+	cache_free_batch(&batch);
 }
 
 /*
@@ -2617,26 +2639,24 @@ cache_purge_vgone(struct vnode *vp)
 void
 cache_purge_negative(struct vnode *vp)
 {
-	TAILQ_HEAD(, namecache) ncps;
+	struct cache_freebatch batch;
 	struct namecache *ncp, *nnp;
 	struct mtx *vlp;
 
 	SDT_PROBE1(vfs, namecache, purge_negative, done, vp);
 	if (LIST_EMPTY(&vp->v_cache_src))
 		return;
-	TAILQ_INIT(&ncps);
+	TAILQ_INIT(&batch);
 	vlp = VP2VNODELOCK(vp);
 	mtx_lock(vlp);
 	LIST_FOREACH_SAFE(ncp, &vp->v_cache_src, nc_src, nnp) {
 		if (!(ncp->nc_flag & NCF_NEGATIVE))
 			continue;
 		cache_zap_negative_locked_vnode_kl(ncp, vp);
-		TAILQ_INSERT_TAIL(&ncps, ncp, nc_dst);
+		TAILQ_INSERT_TAIL(&batch, ncp, nc_dst);
 	}
 	mtx_unlock(vlp);
-	TAILQ_FOREACH_SAFE(ncp, &ncps, nc_dst, nnp) {
-		cache_free(ncp);
-	}
+	cache_free_batch(&batch);
 }
 
 void


More information about the svn-src-head mailing list