Module Name: src Committed By: tls Date: Sun Aug 10 06:59:13 UTC 2014
Modified Files: src/usr.bin/vmstat [tls-earlyentropy]: Makefile drvstats.c vmstat.c Log Message: Rebase. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.30.18.1 src/usr.bin/vmstat/Makefile cvs rdiff -u -r1.6 -r1.6.6.1 src/usr.bin/vmstat/drvstats.c cvs rdiff -u -r1.191 -r1.191.2.1 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/usr.bin/vmstat/Makefile diff -u src/usr.bin/vmstat/Makefile:1.30 src/usr.bin/vmstat/Makefile:1.30.18.1 --- src/usr.bin/vmstat/Makefile:1.30 Wed Aug 17 13:54:31 2011 +++ src/usr.bin/vmstat/Makefile Sun Aug 10 06:59:13 2014 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.30 2011/08/17 13:54:31 christos Exp $ +# $NetBSD: Makefile,v 1.30.18.1 2014/08/10 06:59:13 tls Exp $ # @(#)Makefile 8.1 (Berkeley) 6/6/93 .include <bsd.own.mk> Index: src/usr.bin/vmstat/drvstats.c diff -u src/usr.bin/vmstat/drvstats.c:1.6 src/usr.bin/vmstat/drvstats.c:1.6.6.1 --- src/usr.bin/vmstat/drvstats.c:1.6 Tue Nov 13 14:09:58 2012 +++ src/usr.bin/vmstat/drvstats.c Sun Aug 10 06:59:13 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: drvstats.c,v 1.6 2012/11/13 14:09:58 chs Exp $ */ +/* $NetBSD: drvstats.c,v 1.6.6.1 2014/08/10 06:59:13 tls Exp $ */ /* * Copyright (c) 1996 John M. Vinopal @@ -40,42 +40,18 @@ #include <err.h> #include <fcntl.h> -#include <kvm.h> #include <limits.h> -#include <nlist.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "drvstats.h" -static struct nlist namelist[] = { -#define X_TK_NIN 0 - { .n_name = "_tk_nin" }, /* tty characters in */ -#define X_TK_NOUT 1 - { .n_name = "_tk_nout" }, /* tty characters out */ -#define X_HZ 2 - { .n_name = "_hz" }, /* ticks per second */ -#define X_STATHZ 3 - { .n_name = "_stathz" }, -#define X_DRIVE_COUNT 4 - { .n_name = "_iostat_count" }, /* number of drives */ -#define X_DRIVELIST 5 - { .n_name = "_iostatlist" }, /* TAILQ of drives */ - { .n_name = NULL }, -}; - /* Structures to hold the statistics. */ struct _drive cur, last; -/* Kernel pointers: nlistf and memf defined in calling program. */ -static kvm_t *kd = NULL; -extern char *nlistf; -extern char *memf; extern int hz; -/* Pointer to list of drives. */ -static struct io_stats *iostathead = NULL; /* sysctl hw.drivestats buffer. */ static struct io_sysctl *drives = NULL; @@ -84,27 +60,12 @@ size_t ndrive = 0; int *drv_select; char **dr_name; -#define KVM_ERROR(_string) do { \ - warnx("%s", (_string)); \ - errx(1, "%s", kvm_geterr(kd)); \ -} while (/* CONSTCOND */0) - -/* - * Dereference the namelist pointer `v' and fill in the local copy - * 'p' which is of size 's'. - */ -#define deref_nl(v, p, s) do { \ - deref_kptr((void *)namelist[(v)].n_value, (p), (s)); \ -} while (/* CONSTCOND */0) - /* Missing from <sys/time.h> */ #define timerset(tvp, uvp) do { \ ((uvp)->tv_sec = (tvp)->tv_sec); \ ((uvp)->tv_usec = (tvp)->tv_usec); \ } while (/* CONSTCOND */0) -static void deref_kptr(void *, void *, size_t); - /* * Take the delta between the present values and the last recorded * values, storing the present values in the 'last' structure, and @@ -183,70 +144,44 @@ cpuswap(void) void drvreadstats(void) { - struct io_stats cur_drive, *p; size_t size, i; int mib[3]; - p = iostathead; - - if (memf == NULL) { - mib[0] = CTL_HW; - mib[1] = HW_IOSTATS; - mib[2] = sizeof(struct io_sysctl); - - size = ndrive * sizeof(struct io_sysctl); - if (sysctl(mib, 3, drives, &size, NULL, 0) < 0) - err(1, "sysctl hw.iostats failed"); - for (i = 0; i < ndrive; i++) { - cur.rxfer[i] = drives[i].rxfer; - cur.wxfer[i] = drives[i].wxfer; - cur.seek[i] = drives[i].seek; - cur.rbytes[i] = drives[i].rbytes; - cur.wbytes[i] = drives[i].wbytes; - cur.time[i].tv_sec = drives[i].time_sec; - cur.time[i].tv_usec = drives[i].time_usec; - } + mib[0] = CTL_HW; + mib[1] = HW_IOSTATS; + mib[2] = sizeof(struct io_sysctl); + + size = ndrive * sizeof(struct io_sysctl); + if (sysctl(mib, 3, drives, &size, NULL, 0) < 0) + err(1, "sysctl hw.iostats failed"); + for (i = 0; i < ndrive; i++) { + cur.rxfer[i] = drives[i].rxfer; + cur.wxfer[i] = drives[i].wxfer; + cur.seek[i] = drives[i].seek; + cur.rbytes[i] = drives[i].rbytes; + cur.wbytes[i] = drives[i].wbytes; + cur.time[i].tv_sec = drives[i].time_sec; + cur.time[i].tv_usec = drives[i].time_usec; + } mib[0] = CTL_KERN; - mib[1] = KERN_TKSTAT; - mib[2] = KERN_TKSTAT_NIN; - size = sizeof(cur.tk_nin); - if (sysctl(mib, 3, &cur.tk_nin, &size, NULL, 0) < 0) - cur.tk_nin = 0; - - mib[2] = KERN_TKSTAT_NOUT; - size = sizeof(cur.tk_nout); - if (sysctl(mib, 3, &cur.tk_nout, &size, NULL, 0) < 0) - cur.tk_nout = 0; - } else { - for (i = 0; i < ndrive; i++) { - deref_kptr(p, &cur_drive, sizeof(cur_drive)); - cur.rxfer[i] = cur_drive.io_rxfer; - cur.wxfer[i] = cur_drive.io_wxfer; - cur.seek[i] = cur_drive.io_seek; - cur.rbytes[i] = cur_drive.io_rbytes; - cur.wbytes[i] = cur_drive.io_wbytes; - timerset(&(cur_drive.io_time), &(cur.time[i])); - p = cur_drive.io_link.tqe_next; - } + mib[1] = KERN_TKSTAT; + mib[2] = KERN_TKSTAT_NIN; + size = sizeof(cur.tk_nin); + if (sysctl(mib, 3, &cur.tk_nin, &size, NULL, 0) < 0) + cur.tk_nin = 0; + + mib[2] = KERN_TKSTAT_NOUT; + size = sizeof(cur.tk_nout); + if (sysctl(mib, 3, &cur.tk_nout, &size, NULL, 0) < 0) + cur.tk_nout = 0; - deref_nl(X_TK_NIN, &cur.tk_nin, sizeof(cur.tk_nin)); - deref_nl(X_TK_NOUT, &cur.tk_nout, sizeof(cur.tk_nout)); - } - - /* - * XXX Need to locate the `correct' CPU when looking for this - * XXX in crash dumps. Just don't report it for now, in that - * XXX case. - */ size = sizeof(cur.cp_time); (void)memset(cur.cp_time, 0, size); - if (memf == NULL) { - mib[0] = CTL_KERN; - mib[1] = KERN_CP_TIME; - if (sysctl(mib, 2, cur.cp_time, &size, NULL, 0) < 0) - (void)memset(cur.cp_time, 0, sizeof(cur.cp_time)); - } + mib[0] = CTL_KERN; + mib[1] = KERN_CP_TIME; + if (sysctl(mib, 2, cur.cp_time, &size, NULL, 0) < 0) + (void)memset(cur.cp_time, 0, sizeof(cur.cp_time)); } /* @@ -259,22 +194,17 @@ tkreadstats(void) size_t size; int mib[3]; - if (memf == NULL) { - mib[0] = CTL_KERN; - mib[1] = KERN_TKSTAT; - mib[2] = KERN_TKSTAT_NIN; - size = sizeof(cur.tk_nin); - if (sysctl(mib, 3, &cur.tk_nin, &size, NULL, 0) < 0) - cur.tk_nin = 0; - - mib[2] = KERN_TKSTAT_NOUT; - size = sizeof(cur.tk_nout); - if (sysctl(mib, 3, &cur.tk_nout, &size, NULL, 0) < 0) - cur.tk_nout = 0; - } else { - deref_nl(X_TK_NIN, &cur.tk_nin, sizeof(cur.tk_nin)); - deref_nl(X_TK_NOUT, &cur.tk_nout, sizeof(cur.tk_nout)); - } + mib[0] = CTL_KERN; + mib[1] = KERN_TKSTAT; + mib[2] = KERN_TKSTAT_NIN; + size = sizeof(cur.tk_nin); + if (sysctl(mib, 3, &cur.tk_nin, &size, NULL, 0) < 0) + cur.tk_nin = 0; + + mib[2] = KERN_TKSTAT_NOUT; + size = sizeof(cur.tk_nout); + if (sysctl(mib, 3, &cur.tk_nout, &size, NULL, 0) < 0) + cur.tk_nout = 0; } /* @@ -287,19 +217,12 @@ cpureadstats(void) size_t size; int mib[2]; - /* - * XXX Need to locate the `correct' CPU when looking for this - * XXX in crash dumps. Just don't report it for now, in that - * XXX case. - */ size = sizeof(cur.cp_time); (void)memset(cur.cp_time, 0, size); - if (memf == NULL) { - mib[0] = CTL_KERN; - mib[1] = KERN_CP_TIME; - if (sysctl(mib, 2, cur.cp_time, &size, NULL, 0) < 0) - (void)memset(cur.cp_time, 0, sizeof(cur.cp_time)); - } + mib[0] = CTL_KERN; + mib[1] = KERN_CP_TIME; + if (sysctl(mib, 2, cur.cp_time, &size, NULL, 0) < 0) + (void)memset(cur.cp_time, 0, sizeof(cur.cp_time)); } /* @@ -309,10 +232,7 @@ cpureadstats(void) int drvinit(int selected) { - struct iostatlist_head iostat_head; - struct io_stats cur_drive, *p; struct clockinfo clockinfo; - char errbuf[_POSIX2_LINE_MAX]; size_t size, i; static int once = 0; int mib[3]; @@ -320,66 +240,34 @@ drvinit(int selected) if (once) return (1); - if (memf == NULL) { - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - size = sizeof(cur.cp_ncpu); - if (sysctl(mib, 2, &cur.cp_ncpu, &size, NULL, 0) == -1) - err(1, "sysctl hw.ncpu failed"); + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + size = sizeof(cur.cp_ncpu); + if (sysctl(mib, 2, &cur.cp_ncpu, &size, NULL, 0) == -1) + err(1, "sysctl hw.ncpu failed"); + + mib[0] = CTL_KERN; + mib[1] = KERN_CLOCKRATE; + size = sizeof(clockinfo); + if (sysctl(mib, 2, &clockinfo, &size, NULL, 0) == -1) + err(1, "sysctl kern.clockrate failed"); + hz = clockinfo.stathz; + if (!hz) + hz = clockinfo.hz; + + mib[0] = CTL_HW; + mib[1] = HW_IOSTATS; + mib[2] = sizeof(struct io_sysctl); + if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) + err(1, "sysctl hw.drivestats failed"); + ndrive = size / sizeof(struct io_sysctl); - mib[0] = CTL_KERN; - mib[1] = KERN_CLOCKRATE; - size = sizeof(clockinfo); - if (sysctl(mib, 2, &clockinfo, &size, NULL, 0) == -1) - err(1, "sysctl kern.clockrate failed"); - hz = clockinfo.stathz; - if (!hz) - hz = clockinfo.hz; - - mib[0] = CTL_HW; - mib[1] = HW_IOSTATS; - mib[2] = sizeof(struct io_sysctl); - if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) - err(1, "sysctl hw.drivestats failed"); - ndrive = size / sizeof(struct io_sysctl); - - if (size == 0) { - warnx("No drives attached."); - } else { - drives = (struct io_sysctl *)malloc(size); - if (drives == NULL) - errx(1, "Memory allocation failure."); - } + if (size == 0) { + warnx("No drives attached."); } else { - int drive_count; - /* Open the kernel. */ - if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, - errbuf)) == NULL) - errx(1, "kvm_openfiles: %s", errbuf); - - /* Obtain the namelist symbols from the kernel. */ - if (kvm_nlist(kd, namelist)) - KVM_ERROR("kvm_nlist failed to read symbols."); - - /* Get the number of attached drives. */ - deref_nl(X_DRIVE_COUNT, &drive_count, sizeof(drive_count)); - - if (drive_count < 0) - errx(1, "invalid _drive_count %d.", drive_count); - else if (drive_count == 0) { - warnx("No drives attached."); - } else { - /* Get a pointer to the first drive. */ - deref_nl(X_DRIVELIST, &iostat_head, - sizeof(iostat_head)); - iostathead = iostat_head.tqh_first; - } - ndrive = drive_count; - - /* Get ticks per second. */ - deref_nl(X_STATHZ, &hz, sizeof(hz)); - if (!hz) - deref_nl(X_HZ, &hz, sizeof(hz)); + drives = (struct io_sysctl *)malloc(size); + if (drives == NULL) + errx(1, "Memory allocation failure."); } /* Allocate space for the statistics. */ @@ -412,48 +300,17 @@ drvinit(int selected) dr_name = cur.name; /* Read the drive names and set intial selection. */ - if (memf == NULL) { - mib[0] = CTL_HW; /* Should be still set from */ - mib[1] = HW_IOSTATS; /* ... above, but be safe... */ - mib[2] = sizeof(struct io_sysctl); - if (sysctl(mib, 3, drives, &size, NULL, 0) == -1) - err(1, "sysctl hw.iostats failed"); - for (i = 0; i < ndrive; i++) { - cur.name[i] = drives[i].name; - cur.select[i] = selected; - } - } else { - p = iostathead; - for (i = 0; i < ndrive; i++) { - deref_kptr(p, &cur_drive, sizeof(cur_drive)); - cur.name[i] = strdup(cur_drive.io_name); - if (!cur.name[i]) - err(1, "strdup"); - cur.select[i] = selected; - - p = cur_drive.io_link.tqe_next; - } + mib[0] = CTL_HW; /* Should be still set from */ + mib[1] = HW_IOSTATS; /* ... above, but be safe... */ + mib[2] = sizeof(struct io_sysctl); + if (sysctl(mib, 3, drives, &size, NULL, 0) == -1) + err(1, "sysctl hw.iostats failed"); + for (i = 0; i < ndrive; i++) { + cur.name[i] = drives[i].name; + cur.select[i] = selected; } /* Never do this initialization again. */ once = 1; return (1); } - -/* - * Dereference the kernel pointer `kptr' and fill in the local copy - * pointed to by `ptr'. The storage space must be pre-allocated, - * and the size of the copy passed in `len'. - */ -static void -deref_kptr(void *kptr, void *ptr, size_t len) -{ - char buf[128]; - - if ((size_t)kvm_read(kd, (u_long)kptr, (char *)ptr, len) != len) { - (void)memset(buf, 0, sizeof(buf)); - (void)snprintf(buf, sizeof buf, "can't dereference kptr 0x%lx", - (u_long)kptr); - KVM_ERROR(buf); - } -} Index: src/usr.bin/vmstat/vmstat.c diff -u src/usr.bin/vmstat/vmstat.c:1.191 src/usr.bin/vmstat/vmstat.c:1.191.2.1 --- src/usr.bin/vmstat/vmstat.c:1.191 Wed Feb 19 20:42:14 2014 +++ src/usr.bin/vmstat/vmstat.c Sun Aug 10 06:59:13 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vmstat.c,v 1.191 2014/02/19 20:42:14 dsl Exp $ */ +/* $NetBSD: vmstat.c,v 1.191.2.1 2014/08/10 06:59:13 tls 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.191 2014/02/19 20:42:14 dsl Exp $"); +__RCSID("$NetBSD: vmstat.c,v 1.191.2.1 2014/08/10 06:59:13 tls Exp $"); #endif #endif /* not lint */ @@ -142,8 +142,6 @@ struct cpu_info { # include <sys/cpu.h> #endif -struct cpu_info **cpu_infos; - /* * General namelist */ @@ -250,7 +248,7 @@ struct cpu_counter { uint64_t nsoft; } cpucounter, ocpucounter; -struct uvmexp uvmexp, ouvmexp; +struct uvmexp_sysctl uvmexp, ouvmexp; int ndrives; int winlines = 20; @@ -306,7 +304,7 @@ void needhdr(int); void getnlist(int); long getuptime(void); void printhdr(void); -long pct(long, long); +long pct(u_long, u_long); __dead static void usage(void); void doforkst(void); @@ -322,6 +320,7 @@ char *nlistf, *memf; /* allow old usage [vmstat 1] */ #define BACKWARD_COMPATIBILITY +static const int clockrate_mib[] = { CTL_KERN, KERN_CLOCKRATE }; static const int vmmeter_mib[] = { CTL_VM, VM_METER }; static const int uvmexp2_mib[] = { CTL_VM, VM_UVMEXP2 }; static const int boottime_mib[] = { CTL_KERN, KERN_BOOTTIME }; @@ -724,12 +723,20 @@ dovmstat(struct timespec *interval, int halfuptime = uptime / 2; (void)signal(SIGCONT, needhdr); - if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0) - kread(namelist, X_STATHZ, &hz, sizeof(hz)); - if (!hz) - kread(namelist, X_HZ, &hz, sizeof(hz)); - - kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos)); + if (memf != NULL) { + if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0) + kread(namelist, X_STATHZ, &hz, sizeof(hz)); + if (!hz) + kread(namelist, X_HZ, &hz, sizeof(hz)); + } else { + struct clockinfo clockinfo; + size = sizeof(clockinfo); + if (sysctl(clockrate_mib, 2, &clockinfo, &size, NULL, 0) == -1) + err(1, "sysctl kern.clockrate failed"); + hz = clockinfo.stathz; + if (!hz) + hz = clockinfo.hz; + } for (hdrcnt = 1;;) { if (!--hdrcnt) @@ -738,14 +745,22 @@ dovmstat(struct timespec *interval, int cpureadstats(); drvreadstats(); tkreadstats(); - kread(namelist, X_UVMEXP, &uvmexp, sizeof(uvmexp)); if (memf != NULL) { + struct uvmexp uvmexp_kernel; /* * XXX Can't do this if we're reading a crash * XXX dump because they're lazily-calculated. */ warnx("Unable to get vmtotals from crash dump."); (void)memset(&total, 0, sizeof(total)); + kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); +#define COPY(field) uvmexp.field = uvmexp_kernel.field + COPY(pdreact); + COPY(pageins); + COPY(pgswapout); + COPY(pdfreed); + COPY(pdscans); +#undef COPY } else { size = sizeof(total); if (sysctl(vmmeter_mib, __arraycount(vmmeter_mib), @@ -753,6 +768,10 @@ dovmstat(struct timespec *interval, int warn("Can't get vmtotals"); (void)memset(&total, 0, sizeof(total)); } + size = sizeof(uvmexp); + if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, + &size, NULL, 0) == -1) + warn("sysctl vm.uvmexp2 failed"); } cpucounters(&cpucounter); ovflw = 0; @@ -833,7 +852,7 @@ needhdr(int dummy) } long -pct(long top, long bot) +pct(u_long top, u_long bot) { long ans; @@ -843,14 +862,13 @@ pct(long top, long bot) return (ans); } -#define PCT(top, bot) (int)pct((long)(top), (long)(bot)) +#define PCT(top, bot) (int)pct((u_long)(top), (u_long)(bot)) void dosum(void) { - struct nchstats nchstats; - u_long nchtotal; - struct uvmexp_sysctl uvmexp2; + struct nchstats_sysctl nch_stats; + uint64_t nchtotal; size_t ssize; int active_kernel; struct cpu_counter cc; @@ -860,49 +878,113 @@ dosum(void) * are now estimated by the kernel and sadly * can not easily be dug out of a crash dump. */ - ssize = sizeof(uvmexp2); - memset(&uvmexp2, 0, ssize); + ssize = sizeof(uvmexp); + memset(&uvmexp, 0, ssize); active_kernel = (memf == NULL); if (active_kernel) { /* only on active kernel */ - if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp2, + if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, &ssize, NULL, 0) == -1) warn("sysctl vm.uvmexp2 failed"); + } else { + struct uvmexp uvmexp_kernel; + kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); +#define COPY(field) uvmexp.field = uvmexp_kernel.field + COPY(pagesize); + COPY(ncolors); + COPY(npages); + COPY(free); + COPY(paging); + COPY(wired); + COPY(zeropages); + COPY(reserve_pagedaemon); + COPY(reserve_kernel); + COPY(anonpages); + COPY(filepages); + COPY(execpages); + COPY(freemin); + COPY(freetarg); + COPY(wiredmax); + COPY(nswapdev); + COPY(swpages); + COPY(swpginuse); + COPY(nswget); + COPY(pageins); + COPY(pdpageouts); + COPY(pgswapin); + COPY(pgswapout); + COPY(forks); + COPY(forks_ppwait); + COPY(forks_sharevm); + COPY(pga_zerohit); + COPY(pga_zeromiss); + COPY(zeroaborts); + COPY(colorhit); + COPY(colormiss); + COPY(cpuhit); + COPY(cpumiss); + COPY(fltnoram); + COPY(fltnoanon); + COPY(fltpgwait); + COPY(fltpgrele); + COPY(fltrelck); + COPY(fltrelckok); + COPY(fltanget); + COPY(fltanretry); + COPY(fltamcopy); + COPY(fltamcopy); + COPY(fltnomap); + COPY(fltlget); + COPY(fltget); + COPY(flt_anon); + COPY(flt_acow); + COPY(flt_obj); + COPY(flt_prcopy); + COPY(flt_przero); + COPY(pdwoke); + COPY(pdrevs); + COPY(pdfreed); + COPY(pdscans); + COPY(pdanscan); + COPY(pdobscan); + COPY(pdreact); + COPY(pdbusy); + COPY(pdpending); + COPY(pddeact); +#undef COPY } - kread(namelist, X_UVMEXP, &uvmexp, sizeof(uvmexp)); - (void)printf("%9u bytes per page\n", uvmexp.pagesize); + (void)printf("%9" PRIu64 " bytes per page\n", uvmexp.pagesize); - (void)printf("%9u page color%s\n", + (void)printf("%9" PRIu64 " page color%s\n", uvmexp.ncolors, uvmexp.ncolors == 1 ? "" : "s"); - (void)printf("%9u pages managed\n", uvmexp.npages); - (void)printf("%9u pages free\n", uvmexp.free); + (void)printf("%9" PRIu64 " pages managed\n", uvmexp.npages); + (void)printf("%9" PRIu64 " pages free\n", uvmexp.free); if (active_kernel) { - (void)printf("%9" PRIu64 " pages active\n", uvmexp2.active); - (void)printf("%9" PRIu64 " pages inactive\n", uvmexp2.inactive); + (void)printf("%9" PRIu64 " pages active\n", uvmexp.active); + (void)printf("%9" PRIu64 " pages inactive\n", uvmexp.inactive); } - (void)printf("%9u pages paging\n", uvmexp.paging); - (void)printf("%9u pages wired\n", uvmexp.wired); - (void)printf("%9u zero pages\n", uvmexp.zeropages); - (void)printf("%9u reserve pagedaemon pages\n", + (void)printf("%9" PRIu64 " pages paging\n", uvmexp.paging); + (void)printf("%9" PRIu64 " pages wired\n", uvmexp.wired); + (void)printf("%9" PRIu64 " zero pages\n", uvmexp.zeropages); + (void)printf("%9" PRIu64 " reserve pagedaemon pages\n", uvmexp.reserve_pagedaemon); - (void)printf("%9u reserve kernel pages\n", uvmexp.reserve_kernel); - (void)printf("%9u anonymous pages\n", uvmexp.anonpages); - (void)printf("%9u cached file pages\n", uvmexp.filepages); - (void)printf("%9u cached executable pages\n", uvmexp.execpages); - - (void)printf("%9u minimum free pages\n", uvmexp.freemin); - (void)printf("%9u target free pages\n", uvmexp.freetarg); - (void)printf("%9u maximum wired pages\n", uvmexp.wiredmax); - - (void)printf("%9u swap devices\n", uvmexp.nswapdev); - (void)printf("%9u swap pages\n", uvmexp.swpages); - (void)printf("%9u swap pages in use\n", uvmexp.swpginuse); - (void)printf("%9u swap allocations\n", uvmexp.nswget); + (void)printf("%9" PRIu64 " reserve kernel pages\n", uvmexp.reserve_kernel); + (void)printf("%9" PRIu64 " anonymous pages\n", uvmexp.anonpages); + (void)printf("%9" PRIu64 " cached file pages\n", uvmexp.filepages); + (void)printf("%9" PRIu64 " cached executable pages\n", uvmexp.execpages); + + (void)printf("%9" PRIu64 " minimum free pages\n", uvmexp.freemin); + (void)printf("%9" PRIu64 " target free pages\n", uvmexp.freetarg); + (void)printf("%9" PRIu64 " maximum wired pages\n", uvmexp.wiredmax); + + (void)printf("%9" PRIu64 " swap devices\n", uvmexp.nswapdev); + (void)printf("%9" PRIu64 " swap pages\n", uvmexp.swpages); + (void)printf("%9" PRIu64 " swap pages in use\n", uvmexp.swpginuse); + (void)printf("%9" PRIu64 " swap allocations\n", uvmexp.nswget); - kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos)); cpucounters(&cc); (void)printf("%9" PRIu64 " total faults taken\n", cc.nfault); @@ -911,92 +993,128 @@ dosum(void) (void)printf("%9" PRIu64 " CPU context switches\n", cc.nswtch); (void)printf("%9" PRIu64 " software interrupts\n", cc.nsoft); (void)printf("%9" PRIu64 " system calls\n", cc.nsyscall); - (void)printf("%9u pagein requests\n", uvmexp.pageins); - (void)printf("%9u pageout requests\n", uvmexp.pdpageouts); - (void)printf("%9u pages swapped in\n", uvmexp.pgswapin); - (void)printf("%9u pages swapped out\n", uvmexp.pgswapout); - (void)printf("%9u forks total\n", uvmexp.forks); - (void)printf("%9u forks blocked parent\n", uvmexp.forks_ppwait); - (void)printf("%9u forks shared address space with parent\n", + (void)printf("%9" PRIu64 " pagein requests\n", uvmexp.pageins); + (void)printf("%9" PRIu64 " pageout requests\n", uvmexp.pdpageouts); + (void)printf("%9" PRIu64 " pages swapped in\n", uvmexp.pgswapin); + (void)printf("%9" PRIu64 " pages swapped out\n", uvmexp.pgswapout); + (void)printf("%9" PRIu64 " forks total\n", uvmexp.forks); + (void)printf("%9" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait); + (void)printf("%9" PRIu64 " forks shared address space with parent\n", uvmexp.forks_sharevm); - (void)printf("%9u pagealloc zero wanted and avail\n", + (void)printf("%9" PRIu64 " pagealloc zero wanted and avail\n", uvmexp.pga_zerohit); - (void)printf("%9u pagealloc zero wanted and not avail\n", + (void)printf("%9" PRIu64 " pagealloc zero wanted and not avail\n", uvmexp.pga_zeromiss); - (void)printf("%9u aborts of idle page zeroing\n", + (void)printf("%9" PRIu64 " aborts of idle page zeroing\n", uvmexp.zeroaborts); - (void)printf("%9u pagealloc desired color avail\n", + (void)printf("%9" PRIu64 " pagealloc desired color avail\n", uvmexp.colorhit); - (void)printf("%9u pagealloc desired color not avail\n", + (void)printf("%9" PRIu64 " pagealloc desired color not avail\n", uvmexp.colormiss); - (void)printf("%9u pagealloc local cpu avail\n", + (void)printf("%9" PRIu64 " pagealloc local cpu avail\n", uvmexp.cpuhit); - (void)printf("%9u pagealloc local cpu not avail\n", + (void)printf("%9" PRIu64 " pagealloc local cpu not avail\n", uvmexp.cpumiss); - (void)printf("%9u faults with no memory\n", uvmexp.fltnoram); - (void)printf("%9u faults with no anons\n", uvmexp.fltnoanon); - (void)printf("%9u faults had to wait on pages\n", uvmexp.fltpgwait); - (void)printf("%9u faults found released page\n", uvmexp.fltpgrele); - (void)printf("%9u faults relock (%u ok)\n", uvmexp.fltrelck, + (void)printf("%9" PRIu64 " faults with no memory\n", uvmexp.fltnoram); + (void)printf("%9" PRIu64 " faults with no anons\n", uvmexp.fltnoanon); + (void)printf("%9" PRIu64 " faults had to wait on pages\n", uvmexp.fltpgwait); + (void)printf("%9" PRIu64 " faults found released page\n", uvmexp.fltpgrele); + (void)printf("%9" PRIu64 " faults relock (%" PRIu64 " ok)\n", uvmexp.fltrelck, uvmexp.fltrelckok); - (void)printf("%9u anon page faults\n", uvmexp.fltanget); - (void)printf("%9u anon retry faults\n", uvmexp.fltanretry); - (void)printf("%9u amap copy faults\n", uvmexp.fltamcopy); - (void)printf("%9u neighbour anon page faults\n", uvmexp.fltnamap); - (void)printf("%9u neighbour object page faults\n", uvmexp.fltnomap); - (void)printf("%9u locked pager get faults\n", uvmexp.fltlget); - (void)printf("%9u unlocked pager get faults\n", uvmexp.fltget); - (void)printf("%9u anon faults\n", uvmexp.flt_anon); - (void)printf("%9u anon copy on write faults\n", uvmexp.flt_acow); - (void)printf("%9u object faults\n", uvmexp.flt_obj); - (void)printf("%9u promote copy faults\n", uvmexp.flt_prcopy); - (void)printf("%9u promote zero fill faults\n", uvmexp.flt_przero); - - (void)printf("%9u times daemon wokeup\n",uvmexp.pdwoke); - (void)printf("%9u revolutions of the clock hand\n", uvmexp.pdrevs); - (void)printf("%9u pages freed by daemon\n", uvmexp.pdfreed); - (void)printf("%9u pages scanned by daemon\n", uvmexp.pdscans); - (void)printf("%9u anonymous pages scanned by daemon\n", + (void)printf("%9" PRIu64 " anon page faults\n", uvmexp.fltanget); + (void)printf("%9" PRIu64 " anon retry faults\n", uvmexp.fltanretry); + (void)printf("%9" PRIu64 " amap copy faults\n", uvmexp.fltamcopy); + (void)printf("%9" PRIu64 " neighbour anon page faults\n", uvmexp.fltnamap); + (void)printf("%9" PRIu64 " neighbour object page faults\n", uvmexp.fltnomap); + (void)printf("%9" PRIu64 " locked pager get faults\n", uvmexp.fltlget); + (void)printf("%9" PRIu64 " unlocked pager get faults\n", uvmexp.fltget); + (void)printf("%9" PRIu64 " anon faults\n", uvmexp.flt_anon); + (void)printf("%9" PRIu64 " anon copy on write faults\n", uvmexp.flt_acow); + (void)printf("%9" PRIu64 " object faults\n", uvmexp.flt_obj); + (void)printf("%9" PRIu64 " promote copy faults\n", uvmexp.flt_prcopy); + (void)printf("%9" PRIu64 " promote zero fill faults\n", uvmexp.flt_przero); + + (void)printf("%9" PRIu64 " times daemon wokeup\n",uvmexp.pdwoke); + (void)printf("%9" PRIu64 " revolutions of the clock hand\n", uvmexp.pdrevs); + (void)printf("%9" PRIu64 " pages freed by daemon\n", uvmexp.pdfreed); + (void)printf("%9" PRIu64 " pages scanned by daemon\n", uvmexp.pdscans); + (void)printf("%9" PRIu64 " anonymous pages scanned by daemon\n", uvmexp.pdanscan); - (void)printf("%9u object pages scanned by daemon\n", uvmexp.pdobscan); - (void)printf("%9u pages reactivated\n", uvmexp.pdreact); - (void)printf("%9u pages found busy by daemon\n", uvmexp.pdbusy); - (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); + (void)printf("%9" PRIu64 " object pages scanned by daemon\n", uvmexp.pdobscan); + (void)printf("%9" PRIu64 " pages reactivated\n", uvmexp.pdreact); + (void)printf("%9" PRIu64 " pages found busy by daemon\n", uvmexp.pdbusy); + (void)printf("%9" PRIu64 " total pending pageouts\n", uvmexp.pdpending); + (void)printf("%9" PRIu64 " pages deactivated\n", uvmexp.pddeact); + + 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 doforkst(void) { - kread(namelist, X_UVMEXP, &uvmexp, sizeof(uvmexp)); + if (memf != NULL) { + struct uvmexp uvmexp_kernel; + kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); +#define COPY(field) uvmexp.field = uvmexp_kernel.field + COPY(forks); + COPY(forks_ppwait); + COPY(forks_sharevm); +#undef COPY + } else { + size_t size = sizeof(uvmexp); + if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, + &size, NULL, 0) == -1) + warn("sysctl vm.uvmexp2 failed"); + } - (void)printf("%u forks total\n", uvmexp.forks); - (void)printf("%u forks blocked parent\n", uvmexp.forks_ppwait); - (void)printf("%u forks shared address space with parent\n", + (void)printf("%" PRIu64 " forks total\n", uvmexp.forks); + (void)printf("%" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait); + (void)printf("%" PRIu64 " forks shared address space with parent\n", uvmexp.forks_sharevm); } @@ -1025,7 +1143,26 @@ drvstats(int *ovflwp) void cpucounters(struct cpu_counter *cc) { - struct cpu_info **slot = cpu_infos; + static struct cpu_info **cpu_infos; + static int initialised; + struct cpu_info **slot; + + if (memf == NULL) { + cc->nintr = uvmexp.intrs; + cc->nsyscall = uvmexp.syscalls; + cc->nswtch = uvmexp.swtch; + cc->nfault = uvmexp.faults; + cc->ntrap = uvmexp.traps; + cc->nsoft = uvmexp.softs; + return; + } + + if (!initialised) { + kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos)); + initialised = 1; + } + + slot = cpu_infos; memset(cc, 0, sizeof(*cc)); @@ -1144,10 +1281,7 @@ doevcnt(int verbose, int type) error = sysctl(mib, __arraycount(mib), buf, &newlen, NULL, 0); if (error) { - /* if the sysctl is unknown, try groveling */ - if (error == ENOENT) - break; - warn("kern.evcnt"); + err(1, "kern.evcnt"); if (buf) free(buf); return; @@ -1220,6 +1354,149 @@ doevcnt(int verbose, int type) "Total", counttotal, counttotal / uptime); } +static void +dopool_sysctl(int verbose, int wide) +{ + uint64_t total, inuse, this_total, this_inuse; + struct { + uint64_t pt_nget; + uint64_t pt_nfail; + uint64_t pt_nput; + uint64_t pt_nout; + uint64_t pt_nitems; + uint64_t pt_npagealloc; + uint64_t pt_npagefree; + uint64_t pt_npages; + } pool_totals; + size_t i, len; + int name_len, ovflw; + struct pool_sysctl *pp, *data; + char in_use[8], avail[8], maxp[32]; + + data = asysctlbyname("kern.pool", &len); + if (data == NULL) + err(1, "failed to reead kern.pool"); + + memset(&pool_totals, 0, sizeof pool_totals); + total = inuse = 0; + len /= sizeof(*data); + + (void)printf("Memory resource pool statistics\n"); + (void)printf( + "%-*s%*s%*s%5s%*s%s%s%*s%*s%6s%s%6s%6s%6s%5s%s%s\n", + wide ? 16 : 11, "Name", + wide ? 6 : 5, "Size", + wide ? 12 : 9, "Requests", + "Fail", + wide ? 12 : 9, "Releases", + wide ? " InUse" : "", + wide ? " Avail" : "", + wide ? 7 : 6, "Pgreq", + wide ? 7 : 6, "Pgrel", + "Npage", + wide ? " PageSz" : "", + "Hiwat", + "Minpg", + "Maxpg", + "Idle", + wide ? " Flags" : "", + wide ? " Util" : ""); + + name_len = MIN((int)sizeof(pp->pr_wchan), wide ? 16 : 11); + for (i = 0; i < len; ++i) { + pp = &data[i]; + if (pp->pr_nget == 0 && !verbose) + continue; + if (pp->pr_maxpages == UINT_MAX) + (void)snprintf(maxp, sizeof(maxp), "inf"); + else + (void)snprintf(maxp, sizeof(maxp), "%" PRIu64, + pp->pr_maxpages); + ovflw = 0; + PRWORD(ovflw, "%-*s", name_len, 0, pp->pr_wchan); + PRWORD(ovflw, " %*" PRIu64, wide ? 6 : 5, 1, pp->pr_size); + PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nget); + pool_totals.pt_nget += pp->pr_nget; + PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_nfail); + pool_totals.pt_nfail += pp->pr_nfail; + PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nput); + pool_totals.pt_nput += pp->pr_nput; + if (wide) { + PRWORD(ovflw, " %*" PRIu64, 7, 1, pp->pr_nout); + pool_totals.pt_nout += pp->pr_nout; + } + if (wide) { + PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_nitems); + pool_totals.pt_nitems += pp->pr_nitems; + } + PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 6, 1, pp->pr_npagealloc); + pool_totals.pt_npagealloc += pp->pr_npagealloc; + PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 6, 1, pp->pr_npagefree); + pool_totals.pt_npagefree += pp->pr_npagefree; + PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_npages); + pool_totals.pt_npages += pp->pr_npages; + if (wide) + PRWORD(ovflw, " %*" PRIu64, 7, 1, pp->pr_pagesize); + PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_hiwat); + PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_minpages); + PRWORD(ovflw, " %*s", 6, 1, maxp); + PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_nidle); + if (wide) + PRWORD(ovflw, " 0x%0*" PRIx64, 4, 1, + pp->pr_flags); + + this_inuse = pp->pr_nout * pp->pr_size; + this_total = pp->pr_npages * pp->pr_pagesize; + if (pp->pr_flags & PR_RECURSIVE) { + /* + * Don't count in-use memory, since it's part + * of another pool and will be accounted for + * there. + */ + total += (this_total - this_inuse); + } else { + inuse += this_inuse; + total += this_total; + } + if (wide) { + if (this_total == 0) + (void)printf(" ---"); + else + (void)printf(" %5.1f%%", + (100.0 * this_inuse) / this_total); + } + (void)printf("\n"); + } + if (wide) { + snprintf(in_use, sizeof in_use, "%7"PRId64, pool_totals.pt_nout); + snprintf(avail, sizeof avail, "%6"PRId64, pool_totals.pt_nitems); + } else { + in_use[0] = '\0'; + avail[0] = '\0'; + } + (void)printf( + "%-*s%*s%*"PRId64"%5"PRId64"%*"PRId64"%s%s%*"PRId64"%*"PRId64"%6"PRId64"\n", + wide ? 16 : 11, "Totals", + wide ? 6 : 5, "", + wide ? 12 : 9, pool_totals.pt_nget, + pool_totals.pt_nfail, + wide ? 12 : 9, pool_totals.pt_nput, + in_use, + avail, + wide ? 7 : 6, pool_totals.pt_npagealloc, + wide ? 7 : 6, pool_totals.pt_npagefree, + pool_totals.pt_npages); + + inuse /= KILO; + total /= KILO; + (void)printf( + "\nIn use %" PRIu64 "K, " + "total allocated %" PRIu64 "K; utilization %.1f%%\n", + inuse, total, (100.0 * inuse) / total); + + free(data); +} + void dopool(int verbose, int wide) { @@ -1243,6 +1520,9 @@ dopool(int verbose, int wide) struct pool_allocator pa; char name[32], maxp[32]; + if (memf == NULL) + return dopool_sysctl(verbose, wide); + memset(&pool_totals, 0, sizeof pool_totals); kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head)); addr = TAILQ_FIRST(&pool_head); @@ -1369,6 +1649,68 @@ dopool(int verbose, int wide) inuse, total, (100.0 * inuse) / total); } +static void +dopoolcache_sysctl(int verbose) +{ + struct pool_sysctl *data, *pp; + size_t i, len; + bool first = true; + int ovflw; + uint64_t tot; + float p; + + data = asysctlbyname("kern.pool", &len); + if (data == NULL) + err(1, "failed to reead kern.pool"); + len /= sizeof(*data); + + for (i = 0; i < len; ++i) { + pp = &data[i]; + if (pp->pr_cache_meta_size == 0) + continue; + + if (pp->pr_cache_nmiss_global == 0 && !verbose) + continue; + + if (first) { + (void)printf("Pool cache statistics.\n"); + (void)printf("%-*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n", + 12, "Name", + 6, "Spin", + 6, "GrpSz", + 5, "Full", + 5, "Emty", + 10, "PoolLayer", + 11, "CacheLayer", + 6, "Hit%", + 12, "CpuLayer", + 6, "Hit%" + ); + first = false; + } + + ovflw = 0; + PRWORD(ovflw, "%-*s", MIN((int)sizeof(pp->pr_wchan), 13), 1, + pp->pr_wchan); + PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_cache_ncontended); + PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_cache_meta_size); + PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_cache_nfull); + PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_cache_nempty); + PRWORD(ovflw, " %*" PRIu64, 10, 1, pp->pr_cache_nmiss_global); + + tot = pp->pr_cache_nhit_global + pp->pr_cache_nmiss_global; + p = pp->pr_cache_nhit_global * 100.0 / tot; + PRWORD(ovflw, " %*" PRIu64, 11, 1, tot); + PRWORD(ovflw, " %*.1f", 6, 1, p); + + tot = pp->pr_cache_nhit_pcpu + pp->pr_cache_nmiss_pcpu; + p = pp->pr_cache_nhit_pcpu * 100.0 / tot; + PRWORD(ovflw, " %*" PRIu64, 12, 1, tot); + PRWORD(ovflw, " %*.1f", 6, 1, p); + printf("\n"); + } +} + void dopoolcache(int verbose) { @@ -1383,6 +1725,9 @@ dopoolcache(int verbose) size_t i; double p; + if (memf == NULL) + return dopoolcache_sysctl(verbose); + kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head)); addr = TAILQ_FIRST(&pool_head); @@ -1470,10 +1815,6 @@ struct kernel_hash { X_BUFHASH, X_BUFHASHTBL, HASH_LIST, offsetof(struct buf, b_hash) }, { - "inode cache (ihash)", - X_IHASH, X_IHASHTBL, - HASH_LIST, offsetof(struct inode, i_hash) - }, { "ipv4 address -> interface hash", X_IFADDRHASH, X_IFADDRHASHTBL, HASH_LIST, offsetof(struct in_ifaddr, ia_hash),