Add -C option to display pool_cache info, eg:

Pool cache statistics.
Name          Spin  Full Empty   PoolLayer  CacheLayer  Hit%    CpuLayer  Hit%
pipepl           0     1     3         385       42862  99.1      985780  95.7
fdescpl          0     0     2         310       31133  99.0     1029620  97.0
cwdipl           0     0     2         310       31227  99.0     1029714  97.0
filepl           0     1     4         680      141415  99.5    24011135  99.4
This commit is contained in:
ad 2007-11-07 00:24:18 +00:00
parent d18c6ca4de
commit 9b336836df
2 changed files with 85 additions and 57 deletions

View File

@ -1,6 +1,6 @@
.\" $NetBSD: vmstat.1,v 1.16 2005/03/10 16:29:04 wiz Exp $
.\" $NetBSD: vmstat.1,v 1.17 2007/11/07 00:24:18 ad Exp $
.\"
.\" Copyright (c) 2000 The NetBSD Foundation, Inc.
.\" Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -60,7 +60,7 @@
.\"
.\" @(#)vmstat.8 8.1 (Berkeley) 6/6/93
.\"
.Dd March 10, 2005
.Dd November 6, 2007
.Dt VMSTAT 1
.Os
.Sh NAME
@ -68,7 +68,7 @@
.Nd report virtual memory statistics
.Sh SYNOPSIS
.Nm
.Op Fl efHiLlmstUvW
.Op Fl CefHiLlmstUvW
.Op Fl c Ar count
.Op Fl h Ar hashname
.Op Fl M Ar core
@ -83,6 +83,11 @@ disk, trap, and CPU activity.
.Pp
The options are as follows:
.Bl -tag -width xxxhistname
.It Fl C
Report on kernel memory caches.
Combine with the
.Fl m
option to see information about memory pools that back the caches.
.It Fl c Ar count
Repeat the display
.Ar count

View File

@ -1,7 +1,7 @@
/* $NetBSD: vmstat.c,v 1.153 2006/10/17 15:13:08 christos Exp $ */
/* $NetBSD: vmstat.c,v 1.154 2007/11/07 00:24:18 ad Exp $ */
/*-
* Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 2000, 2001, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation by:
@ -77,7 +77,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\n\
#if 0
static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95";
#else
__RCSID("$NetBSD: vmstat.c,v 1.153 2006/10/17 15:13:08 christos Exp $");
__RCSID("$NetBSD: vmstat.c,v 1.154 2007/11/07 00:24:18 ad Exp $");
#endif
#endif /* not lint */
@ -251,6 +251,7 @@ kvm_t *kd;
#define HASHSTAT 1<<8
#define HASHLIST 1<<9
#define VMTOTAL 1<<10
#define POOLCACHESTAT 1<<11
/*
* Print single word. `ovflow' is number of characters didn't fit
@ -276,7 +277,7 @@ void dohashstat(int, int, const char *);
void dointr(int verbose);
void domem(void);
void dopool(int, int);
void dopoolcache(struct pool *, int);
void dopoolcache(void);
void dosum(void);
void dovmstat(struct timespec *, int);
void print_total_hdr(void);
@ -318,11 +319,14 @@ main(int argc, char *argv[])
reps = todo = verbose = wide = 0;
interval.tv_sec = 0;
interval.tv_nsec = 0;
while ((c = getopt(argc, argv, "c:efh:HilLM:mN:stu:UvWw:")) != -1) {
while ((c = getopt(argc, argv, "Cc:efh:HilLM:mN:stu:UvWw:")) != -1) {
switch (c) {
case 'c':
reps = atoi(optarg);
break;
case 'C':
todo |= POOLCACHESTAT;
break;
case 'e':
todo |= EVCNTSTAT;
break;
@ -482,6 +486,10 @@ main(int argc, char *argv[])
dopool(verbose, wide);
(void)putchar('\n');
}
if (todo & POOLCACHESTAT) {
dopoolcache();
(void)putchar('\n');
}
if (todo & SUMSTAT) {
dosum();
(void)putchar('\n');
@ -1261,7 +1269,6 @@ dopool(int verbose, int wide)
(100.0 * this_inuse) / this_total);
}
(void)printf("\n");
dopoolcache(pp, verbose);
}
inuse /= KILO;
@ -1272,61 +1279,77 @@ dopool(int verbose, int wide)
}
void
dopoolcache(struct pool *pp, int verbose)
dopoolcache(void)
{
struct pool_cache pool_cache, *pc = &pool_cache;
struct pool_cache_group pool_cache_group, *pcg = &pool_cache_group;
void *addr, *pcg_addr;
int i;
pool_cache_cpu_t cache_cpu, *cc = &cache_cpu;
LIST_HEAD(,pool) pool_head;
struct pool pool, *pp = &pool;
char name[32];
uint64_t cpuhit, cpumiss, tot;
void *addr;
int first, ovflw, i;
double p;
if (verbose < 1)
return;
kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head));
addr = LIST_FIRST(&pool_head);
#define PR_GROUPLIST \
deref_kptr(pcg_addr, pcg, sizeof(*pcg), \
"pool cache group trashed"); \
(void)printf("\t\tgroup %p: avail %d\n", pcg_addr, \
pcg->pcg_avail); \
for (i = 0; i < PCG_NOBJECTS; i++) { \
if (pcg->pcg_objects[i].pcgo_pa != \
POOL_PADDR_INVALID) { \
(void)printf("\t\t\t%p, 0x%llx\n", \
pcg->pcg_objects[i].pcgo_va, \
(unsigned long long) \
pcg->pcg_objects[i].pcgo_pa); \
} else { \
(void)printf("\t\t\t%p\n", \
pcg->pcg_objects[i].pcgo_va); \
} \
}
for (addr = LIST_FIRST(&pp->pr_cachelist); addr != NULL;
addr = LIST_NEXT(pc, pc_poollist)) {
deref_kptr(addr, pc, sizeof(*pc), "pool cache trashed");
(void)printf(
"\t hits %lu misses %lu ngroups %lu nitems %lu\n",
pc->pc_hits, pc->pc_misses, pc->pc_ngroups, pc->pc_nitems);
if (verbose < 2)
for (first = 1; addr != NULL; addr = LIST_NEXT(pp, pr_poollist) ) {
deref_kptr(addr, pp, sizeof(*pp), "pool chain trashed");
if (pp->pr_cache == NULL)
continue;
(void)printf("\t full groups:\n");
for (pcg_addr = LIST_FIRST(&pc->pc_fullgroups);
pcg_addr != NULL; pcg_addr = LIST_NEXT(pcg, pcg_list)) {
PR_GROUPLIST;
deref_kptr(pp->pr_wchan, name, sizeof(name),
"pool wait channel trashed");
deref_kptr(pp->pr_cache, pc, sizeof(*pc), "pool cache trashed");
name[sizeof(name)-1] = '\0';
cpuhit = 0;
cpumiss = 0;
for (i = 0; i < sizeof(pc->pc_cpus) / sizeof(pc->pc_cpus[0]);
i++) {
if ((addr = pc->pc_cpus[i]) == NULL)
continue;
deref_kptr(addr, cc, sizeof(*cc),
"pool cache cpu trashed");
cpuhit += cc->cc_hits;
cpumiss += cc->cc_misses;
}
(void)printf("\t partial groups:\n");
for (pcg_addr = LIST_FIRST(&pc->pc_partgroups);
pcg_addr != NULL; pcg_addr = LIST_NEXT(pcg, pcg_list)) {
PR_GROUPLIST;
}
(void)printf("\t empty groups:\n");
for (pcg_addr = LIST_FIRST(&pc->pc_emptygroups);
pcg_addr != NULL; pcg_addr = LIST_NEXT(pcg, pcg_list)) {
PR_GROUPLIST;
if (first) {
(void)printf("Pool cache statistics.\n");
(void)printf("%-*s%*s%*s%*s%*s%*s%*s%*s%*s\n",
12, "Name",
6, "Spin",
6, "Full",
6, "Empty",
12, "PoolLayer",
12, "CacheLayer",
6, "Hit%",
12, "CpuLayer",
6, "Hit%"
);
first = 0;
}
ovflw = 0;
PRWORD(ovflw, "%-*s", 13, 1, name);
PRWORD(ovflw, " %*llu", 6, 1, (long long)pc->pc_contended);
PRWORD(ovflw, " %*u", 6, 1, pc->pc_nfull);
PRWORD(ovflw, " %*u", 6, 1, pc->pc_nempty);
PRWORD(ovflw, " %*llu", 12, 1, (long long)pc->pc_misses);
tot = pc->pc_hits + pc->pc_misses;
p = pc->pc_hits * 100.0 / (tot);
PRWORD(ovflw, " %*llu", 12, 1, (long long)tot);
PRWORD(ovflw, " %*.1f", 6, 1, p);
tot = cpuhit + cpumiss;
p = cpuhit * 100.0 / (tot);
PRWORD(ovflw, " %*llu", 12, 1, (long long)tot);
PRWORD(ovflw, " %*.1f", 6, 1, p);
printf("\n");
}
#undef PR_GROUPLIST
}
enum hashtype { /* from <sys/systm.h> */