Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136987284
D2265.id8873.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D2265.id8873.diff
View Options
Index: stable/10/sys/kern/vfs_cache.c
===================================================================
--- stable/10/sys/kern/vfs_cache.c
+++ stable/10/sys/kern/vfs_cache.c
@@ -330,23 +330,27 @@
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 @@
}
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.
Index: stable/10/sys/kern/vfs_hash.c
===================================================================
--- stable/10/sys/kern/vfs_hash.c
+++ stable/10/sys/kern/vfs_hash.c
@@ -160,3 +160,40 @@
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);
+}
Index: stable/10/sys/kern/vfs_subr.c
===================================================================
--- stable/10/sys/kern/vfs_subr.c
+++ stable/10/sys/kern/vfs_subr.c
@@ -280,8 +280,25 @@
* 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;
Index: stable/10/sys/sys/vnode.h
===================================================================
--- stable/10/sys/sys/vnode.h
+++ stable/10/sys/sys/vnode.h
@@ -600,6 +600,7 @@
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 @@
/* 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);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 21, 10:23 PM (9 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25813803
Default Alt Text
D2265.id8873.diff (5 KB)
Attached To
Mode
D2265: kern.maxvnodes should be a tunable, and probably shouldn't be run-time modifiable
Attached
Detach File
Event Timeline
Log In to Comment