From owner-dev-commits-src-branches@freebsd.org Thu Feb 4 18:01:52 2021 Return-Path: Delivered-To: dev-commits-src-branches@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 DAA1252A4D8; Thu, 4 Feb 2021 18:01:52 +0000 (UTC) (envelope-from git@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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DWmb44FY7z4hLk; Thu, 4 Feb 2021 18:01:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 799421078E; Thu, 4 Feb 2021 18:01:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 114I1q7X052722; Thu, 4 Feb 2021 18:01:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 114I1q8a052720; Thu, 4 Feb 2021 18:01:52 GMT (envelope-from git) Date: Thu, 4 Feb 2021 18:01:52 GMT Message-Id: <202102041801.114I1q8a052720@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mateusz Guzik Subject: git: 55764c48f5f8 - stable/13 - cache: move hash computation into the parsing loop MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mjg X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 55764c48f5f8535d8441764d392bb90dd6a6c9e0 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Feb 2021 18:01:53 -0000 The branch stable/13 has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=55764c48f5f8535d8441764d392bb90dd6a6c9e0 commit 55764c48f5f8535d8441764d392bb90dd6a6c9e0 Author: Mateusz Guzik AuthorDate: 2021-01-31 18:25:18 +0000 Commit: Mateusz Guzik CommitDate: 2021-02-04 17:59:15 +0000 cache: move hash computation into the parsing loop (cherry picked from commit bbfb1edd70e15241d852d82eb7e1c1049a01b886) --- sys/kern/vfs_cache.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index fe7e70ba1359..b13ebf66c49a 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -722,6 +722,27 @@ cache_get_hash(char *name, u_char len, struct vnode *dvp) return (fnv_32_buf(name, len, dvp->v_nchash)); } +static uint32_t +cache_get_hash_iter_start(struct vnode *dvp) +{ + + return (dvp->v_nchash); +} + +static uint32_t +cache_get_hash_iter(char c, uint32_t hash) +{ + + return (fnv_32_buf(&c, 1, hash)); +} + +static uint32_t +cache_get_hash_iter_finish(uint32_t hash) +{ + + return (hash); +} + static inline struct nchashhead * NCP2BUCKET(struct namecache *ncp) { @@ -3693,11 +3714,11 @@ struct cache_fpl { struct nameidata *ndp; struct componentname *cnp; char *nulchar; - struct pwd **pwd; struct vnode *dvp; struct vnode *tvp; seqc_t dvp_seqc; seqc_t tvp_seqc; + uint32_t hash; struct nameidata_saved snd; struct nameidata_outer snd_outer; int line; @@ -3705,6 +3726,7 @@ struct cache_fpl { bool in_smr; bool fsearch; bool savename; + struct pwd **pwd; #ifdef INVARIANTS struct cache_fpl_debug debug; #endif @@ -4951,6 +4973,7 @@ cache_fplookup_next(struct cache_fpl *fpl) cnp = fpl->cnp; dvp = fpl->dvp; + hash = fpl->hash; if (__predict_false(cnp->cn_nameptr[0] == '.')) { if (cnp->cn_namelen == 1) { @@ -4963,8 +4986,6 @@ cache_fplookup_next(struct cache_fpl *fpl) MPASS(!cache_fpl_isdotdot(cnp)); - hash = cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp); - CK_SLIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen)) @@ -5246,10 +5267,13 @@ cache_fplookup_parse(struct cache_fpl *fpl) { struct nameidata *ndp; struct componentname *cnp; + struct vnode *dvp; char *cp; + uint32_t hash; ndp = fpl->ndp; cnp = fpl->cnp; + dvp = fpl->dvp; /* * Find the end of this path component, it is either / or nul. @@ -5257,6 +5281,8 @@ cache_fplookup_parse(struct cache_fpl *fpl) * Store / as a temporary sentinel so that we only have one character * to test for. Pathnames tend to be short so this should not be * resulting in cache misses. + * + * TODO: fix this to be word-sized. */ KASSERT(&cnp->cn_nameptr[fpl->debug.ni_pathlen - 1] == fpl->nulchar, ("%s: mismatch between pathlen (%zu) and nulchar (%p != %p), string [%s]\n", @@ -5265,17 +5291,30 @@ cache_fplookup_parse(struct cache_fpl *fpl) KASSERT(*fpl->nulchar == '\0', ("%s: expected nul at %p; string [%s]\n", __func__, fpl->nulchar, cnp->cn_pnbuf)); + hash = cache_get_hash_iter_start(dvp); *fpl->nulchar = '/'; for (cp = cnp->cn_nameptr; *cp != '/'; cp++) { KASSERT(*cp != '\0', ("%s: encountered unexpected nul; string [%s]\n", __func__, cnp->cn_nameptr)); + hash = cache_get_hash_iter(*cp, hash); continue; } *fpl->nulchar = '\0'; + fpl->hash = cache_get_hash_iter_finish(hash); cnp->cn_namelen = cp - cnp->cn_nameptr; cache_fpl_pathlen_sub(fpl, cnp->cn_namelen); + +#ifdef INVARIANTS + if (cnp->cn_namelen <= NAME_MAX) { + if (fpl->hash != cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp)) { + panic("%s: mismatched hash for [%s] len %ld", __func__, + cnp->cn_nameptr, cnp->cn_namelen); + } + } +#endif + /* * Hack: we have to check if the found path component's length exceeds * NAME_MAX. However, the condition is very rarely true and check can