svn commit: r366829 - head/sys/kern

Mateusz Guzik mjg at FreeBSD.org
Mon Oct 19 09:52:53 UTC 2020


Author: mjg
Date: Mon Oct 19 09:52:52 2020
New Revision: 366829
URL: https://svnweb.freebsd.org/changeset/base/366829

Log:
  cache: refactor negative promotion/demotion handling
  
  This will simplify policy changes.

Modified:
  head/sys/kern/vfs_cache.c

Modified: head/sys/kern/vfs_cache.c
==============================================================================
--- head/sys/kern/vfs_cache.c	Mon Oct 19 07:26:42 2020	(r366828)
+++ head/sys/kern/vfs_cache.c	Mon Oct 19 09:52:52 2020	(r366829)
@@ -908,11 +908,37 @@ cache_neg_init(struct namecache *ncp)
 	counter_u64_add(neg_created, 1);
 }
 
+static bool
+cache_neg_hit_prep(struct namecache *ncp)
+{
+	struct negstate *ns;
+
+	ns = NCP2NEGSTATE(ncp);
+	if ((ns->neg_flag & NEG_HOT) != 0)
+		return (true);
+	return (false);
+}
+
 /*
+ * Nothing to do here but it is provided for completeness as some
+ * cache_neg_hit_prep callers may end up returning without even
+ * trying to promote.
+ */
+#define cache_neg_hit_abort(ncp)	do { } while (0)
+
+static void
+cache_neg_hit_finish(struct namecache *ncp)
+{
+
+	SDT_PROBE2(vfs, namecache, lookup, hit__negative, ncp->nc_dvp, ncp->nc_name);
+	counter_u64_add(numneghits, 1);
+}
+
+/*
  * Move a negative entry to the hot list.
  */
 static void
-cache_neg_promote(struct namecache *ncp)
+cache_neg_promote_locked(struct namecache *ncp)
 {
 	struct neglist *nl;
 	struct negstate *ns;
@@ -929,6 +955,25 @@ cache_neg_promote(struct namecache *ncp)
 }
 
 /*
+ * Move a hot negative entry to the cold list.
+ */
+static void
+cache_neg_demote_locked(struct namecache *ncp)
+{
+	struct neglist *nl;
+	struct negstate *ns;
+
+	ns = NCP2NEGSTATE(ncp);
+	nl = NCP2NEGLIST(ncp);
+	mtx_assert(&nl->nl_lock, MA_OWNED);
+	MPASS(ns->neg_flag & NEG_HOT);
+	TAILQ_REMOVE(&nl->nl_hotlist, ncp, nc_dst);
+	TAILQ_INSERT_TAIL(&nl->nl_list, ncp, nc_dst);
+	nl->nl_hotnum--;
+	ns->neg_flag &= ~NEG_HOT;
+}
+
+/*
  * Move a negative entry to the hot list if it matches the lookup.
  *
  * We have to take locks, but they may be contended and in the worst
@@ -996,10 +1041,8 @@ cache_neg_promote_cond(struct vnode *dvp, struct compo
 		goto out_abort;
 	}
 
-	cache_neg_promote(ncp);
-
-	SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, ncp->nc_name);
-	counter_u64_add(numneghits, 1);
+	cache_neg_promote_locked(ncp);
+	cache_neg_hit_finish(ncp);
 	vfs_smr_exit();
 	mtx_unlock(&nl->nl_lock);
 	return (true);
@@ -1010,17 +1053,13 @@ out_abort:
 }
 
 static void
-cache_neg_hit(struct namecache *ncp)
+cache_neg_promote(struct namecache *ncp)
 {
 	struct neglist *nl;
-	struct negstate *ns;
 
-	ns = NCP2NEGSTATE(ncp);
-	if ((ns->neg_flag & NEG_HOT) != 0)
-		return;
 	nl = NCP2NEGLIST(ncp);
 	mtx_lock(&nl->nl_lock);
-	cache_neg_promote(ncp);
+	cache_neg_promote_locked(ncp);
 	mtx_unlock(&nl->nl_lock);
 }
 
@@ -1094,11 +1133,7 @@ cache_neg_evict(void)
 	mtx_lock(&nl->nl_lock);
 	ncp = TAILQ_FIRST(&nl->nl_hotlist);
 	if (ncp != NULL) {
-		ns = NCP2NEGSTATE(ncp);
-		TAILQ_REMOVE(&nl->nl_hotlist, ncp, nc_dst);
-		TAILQ_INSERT_TAIL(&nl->nl_list, ncp, nc_dst);
-		nl->nl_hotnum--;
-		ns->neg_flag &= ~NEG_HOT;
+		cache_neg_demote_locked(ncp);
 	}
 	ncp = TAILQ_FIRST(&nl->nl_list);
 	if (ncp == NULL) {
@@ -1542,11 +1577,12 @@ negative_success:
 		}
 	}
 
-	SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, ncp->nc_name);
-	cache_out_ts(ncp, tsp, ticksp);
-	counter_u64_add(numneghits, 1);
 	whiteout = (ncp->nc_flag & NCF_WHITE);
-	cache_neg_hit(ncp);
+	cache_out_ts(ncp, tsp, ticksp);
+	if (cache_neg_hit_prep(ncp))
+		cache_neg_promote(ncp);
+	else
+		cache_neg_hit_finish(ncp);
 	mtx_unlock(dvlp);
 	if (whiteout)
 		cnp->cn_flags |= ISWHITEOUT;
@@ -1653,11 +1689,12 @@ negative_success:
 		}
 	}
 
-	SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, ncp->nc_name);
-	cache_out_ts(ncp, tsp, ticksp);
-	counter_u64_add(numneghits, 1);
 	whiteout = (ncp->nc_flag & NCF_WHITE);
-	cache_neg_hit(ncp);
+	cache_out_ts(ncp, tsp, ticksp);
+	if (cache_neg_hit_prep(ncp))
+		cache_neg_promote(ncp);
+	else
+		cache_neg_hit_finish(ncp);
 	mtx_unlock(blp);
 	if (whiteout)
 		cnp->cn_flags |= ISWHITEOUT;
@@ -1669,11 +1706,10 @@ cache_lookup(struct vnode *dvp, struct vnode **vpp, st
     struct timespec *tsp, int *ticksp)
 {
 	struct namecache *ncp;
-	struct negstate *ns;
 	uint32_t hash;
 	enum vgetstate vs;
 	int error;
-	bool whiteout, neg_hot;
+	bool whiteout, neg_promote;
 	u_short nc_flag;
 
 	MPASS((tsp == NULL && ticksp == NULL) || (tsp != NULL && ticksp != NULL));
@@ -1752,19 +1788,18 @@ negative_success:
 
 	cache_out_ts(ncp, tsp, ticksp);
 	whiteout = (ncp->nc_flag & NCF_WHITE);
-	ns = NCP2NEGSTATE(ncp);
-	neg_hot = ((ns->neg_flag & NEG_HOT) != 0);
+	neg_promote = cache_neg_hit_prep(ncp);
 	if (__predict_false(!cache_ncp_canuse(ncp))) {
+		cache_neg_hit_abort(ncp);
 		vfs_smr_exit();
 		goto out_fallback;
 	}
-	if (!neg_hot) {
+	if (neg_promote) {
 		vfs_smr_exit();
 		if (!cache_neg_promote_cond(dvp, cnp, ncp, hash))
 			goto out_fallback;
 	} else {
-		SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, ncp->nc_name);
-		counter_u64_add(numneghits, 1);
+		cache_neg_hit_finish(ncp);
 		vfs_smr_exit();
 	}
 	if (whiteout)
@@ -3917,12 +3952,9 @@ cache_fplookup_dotdot(struct cache_fpl *fpl)
 static int __noinline
 cache_fplookup_neg(struct cache_fpl *fpl, struct namecache *ncp, uint32_t hash)
 {
-	struct negstate *ns;
-	struct vnode *dvp;
 	u_char nc_flag;
-	bool neg_hot;
+	bool neg_promote;
 
-	dvp = fpl->dvp;
 	nc_flag = atomic_load_char(&ncp->nc_flag);
 	MPASS((nc_flag & NCF_NEGATIVE) != 0);
 	/*
@@ -3936,19 +3968,19 @@ cache_fplookup_neg(struct cache_fpl *fpl, struct namec
 		 */
 		return (cache_fpl_partial(fpl));
 	}
-	ns = NCP2NEGSTATE(ncp);
-	neg_hot = ((ns->neg_flag & NEG_HOT) != 0);
+	neg_promote = cache_neg_hit_prep(ncp);
 	if (__predict_false(!cache_ncp_canuse(ncp))) {
+		cache_neg_hit_abort(ncp);
 		return (cache_fpl_partial(fpl));
 	}
 	if (__predict_false((nc_flag & NCF_WHITE) != 0)) {
+		cache_neg_hit_abort(ncp);
 		return (cache_fpl_partial(fpl));
 	}
-	if (!neg_hot) {
+	if (neg_promote) {
 		return (cache_fplookup_negative_promote(fpl, ncp, hash));
 	}
-	SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, ncp->nc_name);
-	counter_u64_add(numneghits, 1);
+	cache_neg_hit_finish(ncp);
 	cache_fpl_smr_exit(fpl);
 	return (cache_fpl_handled(fpl, ENOENT));
 }


More information about the svn-src-head mailing list