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