svn commit: r288079 - in stable/10/sys: kern sys
Oliver Pinter
oliver.pinter at hardenedbsd.org
Tue Sep 22 06:50:19 UTC 2015
On 9/22/15, Kirk McKusick <mckusick at freebsd.org> wrote:
> Author: mckusick
> Date: Tue Sep 22 00:43:05 2015
> New Revision: 288079
> URL: https://svnweb.freebsd.org/changeset/base/288079
>
> Log:
> MFC of 281677:
>
> More accurately collect name-cache statistics in sysctl functions
> sysctl_debug_hashstat_nchash() and sysctl_debug_hashstat_rawnchash().
> These changes are in preparation for allowing changes in the size
> of the vnode hash tables driven by increases and decreases in the
> maximum number of vnodes in the system.
>
> Reviewed by: kib@
> Phabric: D2265
>
> MFC of 287497:
>
> Track changes to kern.maxvnodes and appropriately increase or decrease
> the size of the name cache hash table (mapping file names to vnodes)
> and the vnode hash table (mapping mount point and inode number to vnode).
> An appropriate locking strategy is the key to changing hash table sizes
> while they are in active use.
>
> Reviewed by: kib
> Tested by: Peter Holm
> Differential Revision: https://reviews.freebsd.org/D2265
>
> Modified:
> stable/10/sys/kern/vfs_cache.c
> stable/10/sys/kern/vfs_hash.c
> stable/10/sys/kern/vfs_subr.c
> stable/10/sys/sys/vnode.h
> Directory Properties:
> stable/10/ (props changed)
>
> Modified: stable/10/sys/kern/vfs_cache.c
> ==============================================================================
> --- stable/10/sys/kern/vfs_cache.c Mon Sep 21 22:34:16 2015 (r288078)
> +++ stable/10/sys/kern/vfs_cache.c Tue Sep 22 00:43:05 2015 (r288079)
> @@ -330,23 +330,27 @@ sysctl_debug_hashstat_rawnchash(SYSCTL_H
> int n_nchash;
> int count;
>
> +retry:
> n_nchash = nchash + 1; /* nchash is max index, not count */
> if (!req->oldptr)
> return SYSCTL_OUT(req, 0, n_nchash * sizeof(int));
> -
> - /* Scan hash tables for applicable entries */
> - for (ncpp = nchashtbl; n_nchash > 0; n_nchash--, ncpp++) {
> - CACHE_RLOCK();
> - count = 0;
> - LIST_FOREACH(ncp, ncpp, nc_hash) {
> - count++;
> - }
> + cntbuf = malloc(n_nchash * sizeof(int), M_TEMP, M_ZERO | M_WAITOK);
> + CACHE_RLOCK();
> + if (n_nchash != nchash + 1) {
> CACHE_RUNLOCK();
> - error = SYSCTL_OUT(req, &count, sizeof(count));
> - if (error)
> - return (error);
> + free(cntbuf, M_TEMP);
> + goto retry;
> }
> - return (0);
> + /* Scan hash tables counting entries */
> + for (ncpp = nchashtbl, i = 0; i < n_nchash; ncpp++, i++)
> + LIST_FOREACH(ncp, ncpp, nc_hash)
> + cntbuf[i]++;
> + CACHE_RUNLOCK();
> + for (error = 0, i = 0; i < n_nchash; i++)
> + if ((error = SYSCTL_OUT(req, &cntbuf[i], sizeof(int))) != 0)
> + break;
> + free(cntbuf, M_TEMP);
> + return (error);
> }
> SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnchash, CTLTYPE_INT|CTLFLAG_RD|
> CTLFLAG_MPSAFE, 0, 0, sysctl_debug_hashstat_rawnchash, "S,int",
> @@ -935,6 +939,44 @@ nchinit(void *dummy __unused)
> }
> SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nchinit, NULL);
>
> +void
> +cache_changesize(int newmaxvnodes)
> +{
> + struct nchashhead *new_nchashtbl, *old_nchashtbl;
> + u_long new_nchash, old_nchash;
> + struct namecache *ncp;
> + uint32_t hash;
> + int i;
> +
> + new_nchashtbl = hashinit(newmaxvnodes * 2, M_VFSCACHE, &new_nchash);
> + /* If same hash table size, nothing to do */
> + if (nchash == new_nchash) {
> + free(new_nchashtbl, M_VFSCACHE);
> + return;
> + }
> + /*
> + * Move everything from the old hash table to the new table.
> + * None of the namecache entries in the table can be removed
> + * because to do so, they have to be removed from the hash table.
> + */
> + CACHE_WLOCK();
> + old_nchashtbl = nchashtbl;
> + old_nchash = nchash;
> + nchashtbl = new_nchashtbl;
> + nchash = new_nchash;
> + for (i = 0; i <= old_nchash; i++) {
> + while ((ncp = LIST_FIRST(&old_nchashtbl[i])) != NULL) {
> + hash = fnv_32_buf(nc_get_name(ncp), ncp->nc_nlen,
> + FNV1_32_INIT);
> + hash = fnv_32_buf(&ncp->nc_dvp, sizeof(ncp->nc_dvp),
> + hash);
> + LIST_REMOVE(ncp, nc_hash);
> + LIST_INSERT_HEAD(NCHHASH(hash), ncp, nc_hash);
> + }
> + }
> + CACHE_WUNLOCK();
> + free(old_nchashtbl, M_VFSCACHE);
> +}
>
> /*
> * Invalidate all entries to a particular vnode.
>
> Modified: stable/10/sys/kern/vfs_hash.c
> ==============================================================================
> --- stable/10/sys/kern/vfs_hash.c Mon Sep 21 22:34:16 2015 (r288078)
> +++ stable/10/sys/kern/vfs_hash.c Tue Sep 22 00:43:05 2015 (r288079)
> @@ -160,3 +160,40 @@ vfs_hash_rehash(struct vnode *vp, u_int
> vp->v_hash = hash;
> mtx_unlock(&vfs_hash_mtx);
> }
> +
> +void
> +vfs_hash_changesize(int newmaxvnodes)
> +{
> + struct vfs_hash_head *vfs_hash_newtbl, *vfs_hash_oldtbl;
> + u_long vfs_hash_newmask, vfs_hash_oldmask;
> + struct vnode *vp;
> + int i;
> +
> + vfs_hash_newtbl = hashinit(newmaxvnodes, M_VFS_HASH,
> + &vfs_hash_newmask);
> + /* If same hash table size, nothing to do */
> + if (vfs_hash_mask == vfs_hash_newmask) {
> + free(vfs_hash_newtbl, M_VFS_HASH);
> + return;
> + }
> + /*
> + * Move everything from the old hash table to the new table.
> + * None of the vnodes in the table can be recycled because to
> + * do so, they have to be removed from the hash table.
> + */
> + rw_wlock(&vfs_hash_lock);
> + vfs_hash_oldtbl = vfs_hash_tbl;
> + vfs_hash_oldmask = vfs_hash_mask;
> + vfs_hash_tbl = vfs_hash_newtbl;
> + vfs_hash_mask = vfs_hash_newmask;
> + for (i = 0; i <= vfs_hash_oldmask; i++) {
> + while ((vp = LIST_FIRST(&vfs_hash_oldtbl[i])) != NULL) {
> + LIST_REMOVE(vp, v_hashlist);
> + LIST_INSERT_HEAD(
> + vfs_hash_bucket(vp->v_mount, vp->v_hash),
> + vp, v_hashlist);
> + }
> + }
> + rw_wunlock(&vfs_hash_lock);
> + free(vfs_hash_oldtbl, M_VFS_HASH);
> +}
>
> Modified: stable/10/sys/kern/vfs_subr.c
> ==============================================================================
> --- stable/10/sys/kern/vfs_subr.c Mon Sep 21 22:34:16 2015 (r288078)
> +++ stable/10/sys/kern/vfs_subr.c Tue Sep 22 00:43:05 2015 (r288079)
> @@ -280,8 +280,25 @@ static enum { SYNCER_RUNNING, SYNCER_SHU
> * XXX desiredvnodes is historical cruft and should not exist.
> */
> int desiredvnodes;
> -SYSCTL_INT(_kern, KERN_MAXVNODES, maxvnodes, CTLFLAG_RW,
> - &desiredvnodes, 0, "Maximum number of vnodes");
> +
> +static int
> +sysctl_update_desiredvnodes(SYSCTL_HANDLER_ARGS)
> +{
> + int error, old_desiredvnodes;
> +
> + old_desiredvnodes = desiredvnodes;
> + if ((error = sysctl_handle_int(oidp, arg1, arg2, req)) != 0)
> + return (error);
> + if (old_desiredvnodes != desiredvnodes) {
> + vfs_hash_changesize(desiredvnodes);
> + cache_changesize(desiredvnodes);
> + }
> + return (0);
> +}
> +
> +SYSCTL_PROC(_kern, KERN_MAXVNODES, maxvnodes,
> + CTLTYPE_INT | CTLFLAG_MPSAFE | CTLFLAG_RW, &desiredvnodes, 0,
> + sysctl_update_desiredvnodes, "I", "Maximum number of vnodes");
> SYSCTL_ULONG(_kern, OID_AUTO, minvnodes, CTLFLAG_RW,
> &wantfreevnodes, 0, "Minimum number of vnodes (legacy)");
> static int vnlru_nowhere;
>
> Modified: stable/10/sys/sys/vnode.h
> ==============================================================================
> --- stable/10/sys/sys/vnode.h Mon Sep 21 22:34:16 2015 (r288078)
> +++ stable/10/sys/sys/vnode.h Tue Sep 22 00:43:05 2015 (r288079)
> @@ -600,6 +600,7 @@ struct vnode;
> typedef int (*vn_get_ino_t)(struct mount *, void *, int, struct vnode **);
>
> /* cache_* may belong in namei.h. */
> +void cache_changesize(int newhashsize);
> #define cache_enter(dvp, vp, cnp) \
> cache_enter_time(dvp, vp, cnp, NULL, NULL)
> void cache_enter_time(struct vnode *dvp, struct vnode *vp,
> @@ -836,6 +837,7 @@ int fifo_printinfo(struct vnode *);
> /* vfs_hash.c */
> typedef int vfs_hash_cmp_t(struct vnode *vp, void *arg);
>
> +void vfs_hash_changesize(int newhashsize);
> int vfs_hash_get(const struct mount *mp, u_int hash, int flags, struct
> thread *td, struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg);
> u_int vfs_hash_index(struct vnode *vp);
> int vfs_hash_insert(struct vnode *vp, u_int hash, int flags, struct thread
> *td, struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg);
Seems like this commit breaks the build:
--- vfs_hash.o ---
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:184:2:
error: implicit declaration of function 'rw_wlock' is invalid in C99
[-Werror,-Wimplicit-function-declaration]
rw_wlock(&vfs_hash_lock);
^
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:184:12:
error: use of undeclared identifier 'vfs_hash_lock'; did you mean
'vfs_hash_mask'?
rw_wlock(&vfs_hash_lock);
^~~~~~~~~~~~~
vfs_hash_mask
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:42:18:
note: 'vfs_hash_mask' declared here
static u_long vfs_hash_mask;
^
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:197:2:
error: implicit declaration of function 'rw_wunlock' is invalid in C99
[-Werror,-Wimplicit-function-declaration]
rw_wunlock(&vfs_hash_lock);
^
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:197:2:
note: did you mean 'rw_wlock'?
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:184:2:
note: 'rw_wlock' declared here
rw_wlock(&vfs_hash_lock);
^
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:197:14:
error: use of undeclared identifier 'vfs_hash_lock'; did you mean
'vfs_hash_mask'?
rw_wunlock(&vfs_hash_lock);
^~~~~~~~~~~~~
vfs_hash_mask
/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/kern/vfs_hash.c:42:18:
note: 'vfs_hash_mask' declared here
static u_long vfs_hash_mask;
^
4 errors generated.
*** [vfs_hash.o] Error code 1
make[2]: stopped in
/usr/obj/jenkins/workspace/HardenedBSD-10-STABLE-amd64/sys/HARDENEDBSD
--- vfs_export.o ---
ctfconvert -L VERSION -g vfs_export.o
http://jenkins.hardenedbsd.org:8180/jenkins/job/HardenedBSD-10-STABLE-amd64/99/console
> _______________________________________________
> svn-src-stable-10 at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
> To unsubscribe, send any mail to
> "svn-src-stable-10-unsubscribe at freebsd.org"
>
More information about the svn-src-stable
mailing list