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:
parent
d18c6ca4de
commit
9b336836df
|
@ -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
|
||||
|
|
|
@ -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> */
|
||||
|
|
Loading…
Reference in New Issue