Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Sep 2015 08:50:10 +0200
From:      Oliver Pinter <oliver.pinter@hardenedbsd.org>
To:        Kirk McKusick <mckusick@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   Re: svn commit: r288079 - in stable/10/sys: kern sys
Message-ID:  <CAPQ4ffuJ-RFEHpBvEQnjJRO=AKJK0wyyrgB1aR5T7MJpptQrJQ@mail.gmail.com>
In-Reply-To: <201509220043.t8M0h6jQ034824@repo.freebsd.org>
References:  <201509220043.t8M0h6jQ034824@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 9/22/15, Kirk McKusick <mckusick@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@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@freebsd.org"
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPQ4ffuJ-RFEHpBvEQnjJRO=AKJK0wyyrgB1aR5T7MJpptQrJQ>