Date: Wed, 27 Nov 2019 01:21:42 +0000 (UTC) From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355125 - head/sys/kern Message-ID: <201911270121.xAR1LgYR035117@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mjg Date: Wed Nov 27 01:21:42 2019 New Revision: 355125 URL: https://svnweb.freebsd.org/changeset/base/355125 Log: cache: stop reusing .. entries on enter It almost never happens in practice anyway. With this eliminated ->nc_vp cannot change vnodes, removing an obstacle on the road to lockless lookup. Modified: head/sys/kern/vfs_cache.c Modified: head/sys/kern/vfs_cache.c ============================================================================== --- head/sys/kern/vfs_cache.c Wed Nov 27 01:20:55 2019 (r355124) +++ head/sys/kern/vfs_cache.c Wed Nov 27 01:21:42 2019 (r355125) @@ -1661,6 +1661,33 @@ cache_enter_unlock(struct celockstate *cel) cache_unlock_vnodes_cel(cel); } +static void __noinline +cache_enter_dotdot_prep(struct vnode *dvp, struct vnode *vp, + struct componentname *cnp) +{ + struct celockstate cel; + struct namecache *ncp; + uint32_t hash; + int len; + + if (dvp->v_cache_dd == NULL) + return; + len = cnp->cn_namelen; + cache_celockstate_init(&cel); + hash = cache_get_hash(cnp->cn_nameptr, len, dvp); + cache_enter_lock_dd(&cel, dvp, vp, hash); + ncp = dvp->v_cache_dd; + if (ncp != NULL && (ncp->nc_flag & NCF_ISDOTDOT)) { + KASSERT(ncp->nc_dvp == dvp, ("wrong isdotdot parent")); + cache_zap_locked(ncp, false); + } else { + ncp = NULL; + } + dvp->v_cache_dd = NULL; + cache_enter_unlock(&cel); + cache_free(ncp); +} + /* * Add an entry to the cache. */ @@ -1672,11 +1699,10 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, struct namecache *ncp, *n2, *ndd; struct namecache_ts *ncp_ts, *n2_ts; struct nchashhead *ncpp; - struct neglist *neglist; uint32_t hash; int flag; int len; - bool neg_locked, held_dvp; + bool held_dvp; u_long lnumcache; CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr); @@ -1690,65 +1716,12 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, return; #endif - cache_celockstate_init(&cel); - ndd = NULL; - ncp_ts = NULL; flag = 0; - if (cnp->cn_nameptr[0] == '.') { + if (__predict_false(cnp->cn_nameptr[0] == '.')) { if (cnp->cn_namelen == 1) return; if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { - len = cnp->cn_namelen; - hash = cache_get_hash(cnp->cn_nameptr, len, dvp); - cache_enter_lock_dd(&cel, dvp, vp, hash); - /* - * If dotdot entry already exists, just retarget it - * to new parent vnode, otherwise continue with new - * namecache entry allocation. - */ - if ((ncp = dvp->v_cache_dd) != NULL && - ncp->nc_flag & NCF_ISDOTDOT) { - KASSERT(ncp->nc_dvp == dvp, - ("wrong isdotdot parent")); - neg_locked = false; - if (ncp->nc_flag & NCF_NEGATIVE || vp == NULL) { - neglist = NCP2NEGLIST(ncp); - mtx_lock(&ncneg_hot.nl_lock); - mtx_lock(&neglist->nl_lock); - neg_locked = true; - } - if (!(ncp->nc_flag & NCF_NEGATIVE)) { - TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, - ncp, nc_dst); - } else { - cache_negative_remove(ncp, true); - } - if (vp != NULL) { - TAILQ_INSERT_HEAD(&vp->v_cache_dst, - ncp, nc_dst); - if (ncp->nc_flag & NCF_HOTNEGATIVE) - numhotneg--; - ncp->nc_flag &= ~(NCF_NEGATIVE|NCF_HOTNEGATIVE); - } else { - if (ncp->nc_flag & NCF_HOTNEGATIVE) { - numhotneg--; - ncp->nc_flag &= ~(NCF_HOTNEGATIVE); - } - ncp->nc_flag |= NCF_NEGATIVE; - cache_negative_insert(ncp, true); - } - if (neg_locked) { - mtx_unlock(&neglist->nl_lock); - mtx_unlock(&ncneg_hot.nl_lock); - } - ncp->nc_vp = vp; - cache_enter_unlock(&cel); - return; - } - dvp->v_cache_dd = NULL; - cache_enter_unlock(&cel); - cache_celockstate_init(&cel); - SDT_PROBE3(vfs, namecache, enter, done, dvp, "..", vp); + cache_enter_dotdot_prep(dvp, vp, cnp); flag = NCF_ISDOTDOT; } } @@ -1761,6 +1734,10 @@ cache_enter_time(struct vnode *dvp, struct vnode *vp, atomic_add_long(&numcache, -1); return; } + + cache_celockstate_init(&cel); + ndd = NULL; + ncp_ts = NULL; held_dvp = false; if (LIST_EMPTY(&dvp->v_cache_src) && flag != NCF_ISDOTDOT) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911270121.xAR1LgYR035117>