From: Christian Schulte Subject: Remove memcpy from cache_lookup.c To: tech@openbsd.org Date: Mon, 6 Apr 2026 00:45:51 +0200 Currently cache_lookup copies the name to lookup to the stack on every call just to perform the lookup. This diff makes memcpy disappear from cache_lookup. By reordering the members of struct namecache it is possible to add a new member nc_nptr by still decreasing it's size on 64 bit machines by 8 bytes. Increases the size by 4 byte on 32 bit machines, though. Index: sys/sys/namei.h =================================================================== RCS file: /cvs/src/sys/sys/namei.h,v diff -u -p -u -r1.51 namei.h --- sys/sys/namei.h 8 Mar 2026 16:41:19 -0000 1.51 +++ sys/sys/namei.h 2 Apr 2026 00:56:06 -0000 @@ -174,13 +174,14 @@ void ndinitat(struct nameidata *ndp, u_l #define NAMECACHE_MAXLEN 31 /* maximum name segment length we bother with */ struct namecache { + struct vnode *nc_dvp; /* vnode of parent of name */ + struct vnode *nc_vp; /* vnode the name refers to */ + char *nc_nptr; /* pointer to segment name */ TAILQ_ENTRY(namecache) nc_lru; /* Regular Entry LRU chain */ TAILQ_ENTRY(namecache) nc_neg; /* Negative Entry LRU chain */ RBT_ENTRY(namecache) n_rbcache; /* Namecache rb tree from vnode */ TAILQ_ENTRY(namecache) nc_me; /* ncp's referring to me */ - struct vnode *nc_dvp; /* vnode of parent of name */ u_long nc_dvpid; /* capability number of nc_dvp */ - struct vnode *nc_vp; /* vnode the name refers to */ u_long nc_vpid; /* capability number of nc_vp */ char nc_nlen; /* length of name */ char nc_name[NAMECACHE_MAXLEN]; /* segment name */ Index: sys/kern/vfs_cache.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_cache.c,v diff -u -p -u -r1.58 vfs_cache.c --- sys/kern/vfs_cache.c 14 Aug 2022 01:58:28 -0000 1.58 +++ sys/kern/vfs_cache.c 2 Apr 2026 00:56:17 -0000 @@ -75,7 +75,7 @@ static inline int namecache_compare(const struct namecache *n1, const struct namecache *n2) { if (n1->nc_nlen == n2->nc_nlen) - return (memcmp(n1->nc_name, n2->nc_name, n1->nc_nlen)); + return (memcmp(n1->nc_nptr, n2->nc_nptr, n1->nc_nlen)); else return (n1->nc_nlen - n2->nc_nlen); } @@ -158,7 +158,7 @@ cache_lookup(struct vnode *dvp, struct v /* lookup in directory vnode's redblack tree */ n.nc_nlen = cnp->cn_namelen; - memcpy(n.nc_name, cnp->cn_nameptr, n.nc_nlen); + n.nc_nptr = cnp->cn_nameptr; ncp = RBT_FIND(namecache_rb_cache, &dvp->v_nc_tree, &n); if (ncp == NULL) { @@ -369,6 +369,7 @@ cache_enter(struct vnode *dvp, struct vn ncp->nc_dvp = dvp; ncp->nc_dvpid = dvp->v_id; ncp->nc_nlen = cnp->cn_namelen; + ncp->nc_nptr = ncp->nc_name; memcpy(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen); if (RBT_EMPTY(namecache_rb_cache, &dvp->v_nc_tree)) { vhold(dvp);