From owner-svn-src-all@freebsd.org Mon Oct 19 18:51:51 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id CA1E9431557; Mon, 19 Oct 2020 18:51:51 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CFQpb53w4z41lk; Mon, 19 Oct 2020 18:51:51 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 91542850C; Mon, 19 Oct 2020 18:51:51 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 09JIppSW016436; Mon, 19 Oct 2020 18:51:51 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 09JIpp1G016435; Mon, 19 Oct 2020 18:51:51 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <202010191851.09JIpp1G016435@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Mon, 19 Oct 2020 18:51:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366846 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: mjg X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 366846 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Oct 2020 18:51:51 -0000 Author: mjg Date: Mon Oct 19 18:51:51 2020 New Revision: 366846 URL: https://svnweb.freebsd.org/changeset/base/366846 Log: cache: promote negative entries based on more than one hit During tinderbox and similar workloads negative entries get at least one hit before they get evicted. In the current scheme this avoidably promotes them. Be conservative and stick to 2 hits for now. Modified: head/sys/kern/vfs_cache.c Modified: head/sys/kern/vfs_cache.c ============================================================================== --- head/sys/kern/vfs_cache.c Mon Oct 19 18:24:06 2020 (r366845) +++ head/sys/kern/vfs_cache.c Mon Oct 19 18:51:51 2020 (r366846) @@ -129,6 +129,7 @@ SDT_PROBE_DECLARE(vfs, namei, lookup, return); */ struct negstate { u_char neg_flag; + u_char neg_hit; }; _Static_assert(sizeof(struct negstate) <= sizeof(struct vnode *), "the state must fit in a union with a pointer without growing it"); @@ -905,18 +906,27 @@ cache_neg_init(struct namecache *ncp) ncp->nc_flag |= NCF_NEGATIVE; ns = NCP2NEGSTATE(ncp); ns->neg_flag = 0; + ns->neg_hit = 0; counter_u64_add(neg_created, 1); } +#define CACHE_NEG_PROMOTION_THRESH 2 + static bool cache_neg_hit_prep(struct namecache *ncp) { struct negstate *ns; + u_char n; ns = NCP2NEGSTATE(ncp); - if ((ns->neg_flag & NEG_HOT) != 0) - return (true); - return (false); + n = atomic_load_char(&ns->neg_hit); + for (;;) { + if (n >= CACHE_NEG_PROMOTION_THRESH) + return (false); + if (atomic_fcmpset_8(&ns->neg_hit, &n, n + 1)) + break; + } + return (n + 1 == CACHE_NEG_PROMOTION_THRESH); } /* @@ -971,6 +981,7 @@ cache_neg_demote_locked(struct namecache *ncp) TAILQ_INSERT_TAIL(&nl->nl_list, ncp, nc_dst); nl->nl_hotnum--; ns->neg_flag &= ~NEG_HOT; + atomic_store_char(&ns->neg_hit, 0); } /* @@ -1098,7 +1109,7 @@ cache_neg_remove(struct namecache *ncp) } static struct neglist * -cache_neg_evict_select(void) +cache_neg_evict_select_list(void) { struct neglist *nl; u_int c; @@ -1112,6 +1123,33 @@ cache_neg_evict_select(void) return (nl); } +static struct namecache * +cache_neg_evict_select_entry(struct neglist *nl) +{ + struct namecache *ncp, *lncp; + struct negstate *ns, *lns; + int i; + + mtx_assert(&nl->nl_evict_lock, MA_OWNED); + mtx_assert(&nl->nl_lock, MA_OWNED); + ncp = TAILQ_FIRST(&nl->nl_list); + if (ncp == NULL) + return (NULL); + lncp = ncp; + lns = NCP2NEGSTATE(lncp); + for (i = 1; i < 4; i++) { + ncp = TAILQ_NEXT(ncp, nc_dst); + if (ncp == NULL) + break; + ns = NCP2NEGSTATE(ncp); + if (ns->neg_hit < lns->neg_hit) { + lncp = ncp; + lns = ns; + } + } + return (lncp); +} + static bool cache_neg_evict(void) { @@ -1125,7 +1163,7 @@ cache_neg_evict(void) u_char nlen; bool evicted; - nl = cache_neg_evict_select(); + nl = cache_neg_evict_select_list(); if (nl == NULL) { return (false); } @@ -1135,7 +1173,7 @@ cache_neg_evict(void) if (ncp != NULL) { cache_neg_demote_locked(ncp); } - ncp = TAILQ_FIRST(&nl->nl_list); + ncp = cache_neg_evict_select_entry(nl); if (ncp == NULL) { counter_u64_add(neg_evict_skipped_empty, 1); mtx_unlock(&nl->nl_lock);