Module Name: src Committed By: joerg Date: Tue Jun 3 21:16:15 UTC 2014
Modified Files: src/sys/kern: vfs_cache.c src/sys/sys: namei.src src/usr.bin/systat: vmstat.c src/usr.bin/vmstat: vmstat.c Log Message: Provide sysctl for namecache statistics. To generate a diff of this commit: cvs rdiff -u -r1.96 -r1.97 src/sys/kern/vfs_cache.c cvs rdiff -u -r1.32 -r1.33 src/sys/sys/namei.src cvs rdiff -u -r1.77 -r1.78 src/usr.bin/systat/vmstat.c cvs rdiff -u -r1.193 -r1.194 src/usr.bin/vmstat/vmstat.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_cache.c diff -u src/sys/kern/vfs_cache.c:1.96 src/sys/kern/vfs_cache.c:1.97 --- src/sys/kern/vfs_cache.c:1.96 Tue Jun 3 19:42:17 2014 +++ src/sys/kern/vfs_cache.c Tue Jun 3 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_cache.c,v 1.96 2014/06/03 19:42:17 joerg Exp $ */ +/* $NetBSD: vfs_cache.c,v 1.97 2014/06/03 21:16:15 joerg Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -58,13 +58,14 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.96 2014/06/03 19:42:17 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.97 2014/06/03 21:16:15 joerg Exp $"); #include "opt_ddb.h" #include "opt_revcache.h" #include <sys/param.h> #include <sys/systm.h> +#include <sys/sysctl.h> #include <sys/time.h> #include <sys/mount.h> #include <sys/vnode.h> @@ -1098,3 +1099,49 @@ namecache_count_2passes(void) COUNT(cpup->cpu_stats, ncs_2passes); mutex_exit(&cpup->cpu_lock); } + +static int +cache_stat_sysctl(SYSCTLFN_ARGS) +{ + struct nchstats_sysctl stats; + + if (oldp == NULL) { + *oldlenp = sizeof(stats); + return 0; + } + + if (*oldlenp < sizeof(stats)) { + *oldlenp = 0; + return 0; + } + + memset(&stats, 0, sizeof(stats)); + + sysctl_unlock(); + cache_lock_cpus(); + stats.ncs_goodhits = nchstats.ncs_goodhits; + stats.ncs_neghits = nchstats.ncs_neghits; + stats.ncs_badhits = nchstats.ncs_badhits; + stats.ncs_falsehits = nchstats.ncs_falsehits; + stats.ncs_miss = nchstats.ncs_miss; + stats.ncs_long = nchstats.ncs_long; + stats.ncs_pass2 = nchstats.ncs_pass2; + stats.ncs_2passes = nchstats.ncs_2passes; + stats.ncs_revhits = nchstats.ncs_revhits; + stats.ncs_revmiss = nchstats.ncs_revmiss; + cache_unlock_cpus(); + sysctl_relock(); + + *oldlenp = sizeof(stats); + return sysctl_copyout(l, &stats, oldp, sizeof(stats)); +} + +SYSCTL_SETUP(sysctl_cache_stat_setup, "vfs.namecache_stats subtree setup") +{ + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_STRUCT, "namecache_stats", + SYSCTL_DESCR("namecache statistics"), + cache_stat_sysctl, 0, NULL, 0, + CTL_VFS, CTL_CREATE, CTL_EOL); +} Index: src/sys/sys/namei.src diff -u src/sys/sys/namei.src:1.32 src/sys/sys/namei.src:1.33 --- src/sys/sys/namei.src:1.32 Tue Jun 3 19:30:29 2014 +++ src/sys/sys/namei.src Tue Jun 3 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: namei.src,v 1.32 2014/06/03 19:30:29 joerg Exp $ */ +/* $NetBSD: namei.src,v 1.33 2014/06/03 21:16:15 joerg Exp $ */ /* * Copyright (c) 1985, 1989, 1991, 1993 @@ -304,6 +304,19 @@ struct nchstats { long ncs_revmiss; /* reverse-cache misses */ }; +struct nchstats_sysctl { + uint64_t ncs_goodhits; /* hits that we can really use */ + uint64_t ncs_neghits; /* negative hits that we can use */ + uint64_t ncs_badhits; /* hits we must drop */ + uint64_t ncs_falsehits; /* hits with id mismatch */ + uint64_t ncs_miss; /* misses */ + uint64_t ncs_long; /* long names that ignore cache */ + uint64_t ncs_pass2; /* names found with passes == 2 */ + uint64_t ncs_2passes; /* number of times we attempt it */ + uint64_t ncs_revhits; /* reverse-cache hits */ + uint64_t ncs_revmiss; /* reverse-cache misses */ +}; + #ifdef _KERNEL extern struct nchstats nchstats; #endif Index: src/usr.bin/systat/vmstat.c diff -u src/usr.bin/systat/vmstat.c:1.77 src/usr.bin/systat/vmstat.c:1.78 --- src/usr.bin/systat/vmstat.c:1.77 Fri Apr 30 16:21:05 2010 +++ src/usr.bin/systat/vmstat.c Tue Jun 3 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vmstat.c,v 1.77 2010/04/30 16:21:05 njoly Exp $ */ +/* $NetBSD: vmstat.c,v 1.78 2014/06/03 21:16:15 joerg Exp $ */ /*- * Copyright (c) 1983, 1989, 1992, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94"; #endif -__RCSID("$NetBSD: vmstat.c,v 1.77 2010/04/30 16:21:05 njoly Exp $"); +__RCSID("$NetBSD: vmstat.c,v 1.78 2014/06/03 21:16:15 joerg Exp $"); #endif /* not lint */ /* @@ -63,7 +63,7 @@ __RCSID("$NetBSD: vmstat.c,v 1.77 2010/0 static struct Info { struct uvmexp_sysctl uvmexp; struct vmtotal Total; - struct nchstats nchstats; + struct nchstats_sysctl nchstats; long nchcount; long *intrcnt; u_int64_t *evcnt; @@ -776,7 +776,12 @@ getinfo(struct Info *stats) cpureadstats(); drvreadstats(); - NREAD(X_NCHSTATS, &stats->nchstats, sizeof stats->nchstats); + size = sizeof(stats->nchstats); + if (sysctlbyname("vfs.namecache_stats", &stats->nchstats, &size, + NULL, 0) < 0) { + error("can't get namecache statistics: %s\n", strerror(errno)); + memset(&stats->nchstats, 0, sizeof(stats->nchstats)); + } if (nintr) NREAD(X_INTRCNT, stats->intrcnt, nintr * LONG); for (i = 0; i < nevcnt; i++) Index: src/usr.bin/vmstat/vmstat.c diff -u src/usr.bin/vmstat/vmstat.c:1.193 src/usr.bin/vmstat/vmstat.c:1.194 --- src/usr.bin/vmstat/vmstat.c:1.193 Mon Jun 2 19:16:10 2014 +++ src/usr.bin/vmstat/vmstat.c Tue Jun 3 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vmstat.c,v 1.193 2014/06/02 19:16:10 joerg Exp $ */ +/* $NetBSD: vmstat.c,v 1.194 2014/06/03 21:16:15 joerg Exp $ */ /*- * Copyright (c) 1998, 2000, 2001, 2007 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; #else -__RCSID("$NetBSD: vmstat.c,v 1.193 2014/06/02 19:16:10 joerg Exp $"); +__RCSID("$NetBSD: vmstat.c,v 1.194 2014/06/03 21:16:15 joerg Exp $"); #endif #endif /* not lint */ @@ -848,8 +848,8 @@ pct(long top, long bot) void dosum(void) { - struct nchstats nchstats; - u_long nchtotal; + struct nchstats_sysctl nch_stats; + uint64_t nchtotal; struct uvmexp_sysctl uvmexp2; size_t ssize; int active_kernel; @@ -965,28 +965,51 @@ dosum(void) (void)printf("%9u total pending pageouts\n", uvmexp.pdpending); (void)printf("%9u pages deactivated\n", uvmexp.pddeact); - kread(namelist, X_NCHSTATS, &nchstats, sizeof(nchstats)); - nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits + - nchstats.ncs_badhits + nchstats.ncs_falsehits + - nchstats.ncs_miss + nchstats.ncs_long; - (void)printf("%9lu total name lookups\n", nchtotal); - (void)printf("%9lu good hits\n", nchstats.ncs_goodhits); - (void)printf("%9lu negative hits\n", nchstats.ncs_neghits); - (void)printf("%9lu bad hits\n", nchstats.ncs_badhits); - (void)printf("%9lu false hits\n", nchstats.ncs_falsehits); - (void)printf("%9lu miss\n", nchstats.ncs_miss); - (void)printf("%9lu too long\n", nchstats.ncs_long); - (void)printf("%9lu pass2 hits\n", nchstats.ncs_pass2); - (void)printf("%9lu 2passes\n", nchstats.ncs_2passes); + if (active_kernel) { + ssize = sizeof(nch_stats); + if (sysctlbyname("vfs.namecache_stats", &nch_stats, &ssize, + NULL, 0)) { + warn("vfs.namecache_stats failed"); + memset(&nch_stats, 0, sizeof(nch_stats)); + } + } else { + struct nchstats nch_stats_kvm; + + kread(namelist, X_NCHSTATS, &nch_stats_kvm, + sizeof(nch_stats_kvm)); + nch_stats.ncs_goodhits = nch_stats_kvm.ncs_goodhits; + nch_stats.ncs_neghits = nch_stats_kvm.ncs_neghits; + nch_stats.ncs_badhits = nch_stats_kvm.ncs_badhits; + nch_stats.ncs_falsehits = nch_stats_kvm.ncs_falsehits; + nch_stats.ncs_miss = nch_stats_kvm.ncs_miss; + nch_stats.ncs_long = nch_stats_kvm.ncs_long; + nch_stats.ncs_pass2 = nch_stats_kvm.ncs_pass2; + nch_stats.ncs_2passes = nch_stats_kvm.ncs_2passes; + nch_stats.ncs_revhits = nch_stats_kvm.ncs_revhits; + nch_stats.ncs_revmiss = nch_stats_kvm.ncs_revmiss; + } + + nchtotal = nch_stats.ncs_goodhits + nch_stats.ncs_neghits + + nch_stats.ncs_badhits + nch_stats.ncs_falsehits + + nch_stats.ncs_miss + nch_stats.ncs_long; + (void)printf("%9" PRIu64 " total name lookups\n", nchtotal); + (void)printf("%9" PRIu64 " good hits\n", nch_stats.ncs_goodhits); + (void)printf("%9" PRIu64 " negative hits\n", nch_stats.ncs_neghits); + (void)printf("%9" PRIu64 " bad hits\n", nch_stats.ncs_badhits); + (void)printf("%9" PRIu64 " false hits\n", nch_stats.ncs_falsehits); + (void)printf("%9" PRIu64 " miss\n", nch_stats.ncs_miss); + (void)printf("%9" PRIu64 " too long\n", nch_stats.ncs_long); + (void)printf("%9" PRIu64 " pass2 hits\n", nch_stats.ncs_pass2); + (void)printf("%9" PRIu64 " 2passes\n", nch_stats.ncs_2passes); (void)printf( "%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n", - "", PCT(nchstats.ncs_goodhits, nchtotal), - PCT(nchstats.ncs_neghits, nchtotal), - PCT(nchstats.ncs_pass2, nchtotal)); + "", PCT(nch_stats.ncs_goodhits, nchtotal), + PCT(nch_stats.ncs_neghits, nchtotal), + PCT(nch_stats.ncs_pass2, nchtotal)); (void)printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "", - PCT(nchstats.ncs_badhits, nchtotal), - PCT(nchstats.ncs_falsehits, nchtotal), - PCT(nchstats.ncs_long, nchtotal)); + PCT(nch_stats.ncs_badhits, nchtotal), + PCT(nch_stats.ncs_falsehits, nchtotal), + PCT(nch_stats.ncs_long, nchtotal)); } void