summaryrefslogtreecommitdiffstats
path: root/sys/nfs/nfs_node.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-04-11 00:39:20 +0000
committerpeter <peter@FreeBSD.org>2001-04-11 00:39:20 +0000
commit8b9d89e1e4b0098c45e5dc980efe68065eb46dba (patch)
tree2d4650820668103fe200ec8941af5e350f402ce9 /sys/nfs/nfs_node.c
parentd212e20c86e42279e24581c24033392cfad8426f (diff)
downloadFreeBSD-src-8b9d89e1e4b0098c45e5dc980efe68065eb46dba.zip
FreeBSD-src-8b9d89e1e4b0098c45e5dc980efe68065eb46dba.tar.gz
Create debug.hashstat.[raw]nchash and debug.hashstat.[raw]nfsnode to
enable easy access to the hash chain stats. The raw prefixed versions dump an integer array to userland with the chain lengths. This cheats and calls it an array of 'struct int' rather than 'int' or sysctl -a faithfully dumps out the 128K array on an average machine. The non-raw versions return 4 integers: count, number of chains used, maximum chain length, and percentage utilization (fixed point, multiplied by 100). The raw forms are more useful for analyzing the hash distribution, while the other form can be read easily by humans and stats loggers.
Diffstat (limited to 'sys/nfs/nfs_node.c')
-rw-r--r--sys/nfs/nfs_node.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c
index a82ad11..0191b66 100644
--- a/sys/nfs/nfs_node.c
+++ b/sys/nfs/nfs_node.c
@@ -45,6 +45,7 @@
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/fnv_hash.h>
+#include <sys/sysctl.h>
#include <vm/vm_zone.h>
@@ -62,6 +63,84 @@ static u_long nfsnodehash;
#define FALSE 0
/*
+ * Grab an atomic snapshot of the nfsnode hash chain lengths
+ */
+SYSCTL_DECL(_debug_hashstat);
+static int
+sysctl_debug_hashstat_rawnfsnode(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ struct nfsnodehashhead *nnpp;
+ struct nfsnode *nnp;
+ int n_nfsnode;
+ int count;
+
+ n_nfsnode = nfsnodehash + 1; /* nfsnodehash = max index, not count */
+ if (!req->oldptr)
+ return SYSCTL_OUT(req, 0, n_nfsnode * sizeof(int));
+
+ /* Scan hash tables for applicable entries */
+ for (nnpp = nfsnodehashtbl; n_nfsnode > 0; n_nfsnode--, nnpp++) {
+ count = 0;
+ LIST_FOREACH(nnp, nnpp, n_hash) {
+ count++;
+ }
+ error = SYSCTL_OUT(req, (caddr_t)&count, sizeof(count));
+ if (error)
+ return (error);
+ }
+ return (0);
+}
+SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnfsnode, CTLTYPE_INT|CTLFLAG_RD,
+ 0, 0, sysctl_debug_hashstat_rawnfsnode, "S,int", "nfsnode chain lengths");
+
+static int
+sysctl_debug_hashstat_nfsnode(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ struct nfsnodehashhead *nnpp;
+ struct nfsnode *nnp;
+ int n_nfsnode;
+ int count, maxlength, used, pct;
+
+ if (!req->oldptr)
+ return SYSCTL_OUT(req, 0, 4 * sizeof(int));
+
+ n_nfsnode = nfsnodehash + 1; /* nfsnodehash = max index, not count */
+ used = 0;
+ maxlength = 0;
+
+ /* Scan hash tables for applicable entries */
+ for (nnpp = nfsnodehashtbl; n_nfsnode > 0; n_nfsnode--, nnpp++) {
+ count = 0;
+ LIST_FOREACH(nnp, nnpp, n_hash) {
+ count++;
+ }
+ if (count)
+ used++;
+ if (maxlength < count)
+ maxlength = count;
+ }
+ n_nfsnode = nfsnodehash + 1;
+ pct = (used * 100 * 100) / n_nfsnode;
+ error = SYSCTL_OUT(req, (caddr_t)&n_nfsnode, sizeof(n_nfsnode));
+ if (error)
+ return (error);
+ error = SYSCTL_OUT(req, (caddr_t)&used, sizeof(used));
+ if (error)
+ return (error);
+ error = SYSCTL_OUT(req, (caddr_t)&maxlength, sizeof(maxlength));
+ if (error)
+ return (error);
+ error = SYSCTL_OUT(req, (caddr_t)&pct, sizeof(pct));
+ if (error)
+ return (error);
+ return (0);
+}
+SYSCTL_PROC(_debug_hashstat, OID_AUTO, nfsnode, CTLTYPE_INT|CTLFLAG_RD,
+ 0, 0, sysctl_debug_hashstat_nfsnode, "I", "nfsnode chain lengths");
+
+/*
* Initialize hash links for nfsnodes
* and build nfsnode free list.
*/
OpenPOWER on IntegriCloud