summaryrefslogtreecommitdiffstats
path: root/usr.bin/vmstat
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-05-29 13:40:00 +0000
committerrwatson <rwatson@FreeBSD.org>2005-05-29 13:40:00 +0000
commitf5b0199972b5e0563c6ea9ef6319ccf723b596f1 (patch)
tree0411e9c0a956564d16827de06fe2eb53a7c39596 /usr.bin/vmstat
parent7035f9f56aa6a07ac9af727380ff3092b79ee9f7 (diff)
downloadFreeBSD-src-f5b0199972b5e0563c6ea9ef6319ccf723b596f1.zip
FreeBSD-src-f5b0199972b5e0563c6ea9ef6319ccf723b596f1.tar.gz
Modify vmstat(8)'s domem() routine, which is responsible for extracting
malloc(9) statistics from kernel memory or a kernel coredump, to catch up with recent changes to adopt per-CPU malloc(9) statistics. The new routines walk the per-CPU statistics pools and coalesce them for presentation to the user.
Diffstat (limited to 'usr.bin/vmstat')
-rw-r--r--usr.bin/vmstat/vmstat.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c
index 717d528..9ee2c36 100644
--- a/usr.bin/vmstat/vmstat.c
+++ b/usr.bin/vmstat/vmstat.c
@@ -897,10 +897,22 @@ dointr(void)
(long long)inttotal, (long long)(inttotal / uptime));
}
+/*
+ * domem() replicates the kernel implementation of kern.malloc by inspecting
+ * kernel data structures, which is appropriate for use on a core dump.
+ * domem() must identify the set of malloc types, walk the list, and coalesce
+ * per-CPU state to report. It relies on direct access to internal kernel
+ * data structures that have a fragile (and intentionally unexposed) ABI.
+ * This logic should not be used by live monitoring tools, which should
+ * instead rely solely on the sysctl interface.
+ */
static void
domem(void)
{
+ struct malloc_type_stats mts_local, *mts;
+ struct malloc_type_internal mti;
struct malloc_type type;
+ int i;
if (kd == NULL) {
dosysctl("kern.malloc");
@@ -924,15 +936,34 @@ domem(void)
sizeof(type))
errx(1, "%s: %p: %s", __func__, type.ks_next,
kvm_geterr(kd));
- if (type.ks_calls == 0)
+ if (kvm_read(kd, (u_long)type.ks_handle, &mti, sizeof(mti)) !=
+ sizeof(mti))
+ errx(1, "%s: %p: %s", __func__, type.ks_handle,
+ kvm_geterr(kd));
+
+ bzero(&mts_local, sizeof(mts_local));
+ for (i = 0; i < MAXCPU; i++) {
+ mts = &mti.mti_stats[i];
+ mts_local.mts_memalloced += mts->mts_memalloced;
+ mts_local.mts_memfreed += mts->mts_memfreed;
+ mts_local.mts_numallocs += mts->mts_numallocs;
+ mts_local.mts_numfrees += mts->mts_numfrees;
+ mts_local.mts_size |= mts->mts_size;
+ }
+ if (mts_local.mts_numallocs == 0)
continue;
+
+ /*
+ * Unlike in kern_malloc.c, we don't mask inter-CPU races, as * vmstat on a core is likely for debugging purposes.
+ */
+
str = kgetstr(type.ks_shortdesc);
- (void)printf("%13s%6lu%6luK%7luK%9llu",
+ (void)printf("%13s%6lu%6luK -%9llu",
str,
- type.ks_inuse,
- (type.ks_memuse + 1023) / 1024,
- (type.ks_maxused + 1023) / 1024,
- (long long unsigned)type.ks_calls);
+ mts_local.mts_numallocs - mts_local.mts_numfrees,
+ ((mts_local.mts_memalloced - mts_local.mts_memfreed) +
+ 1023) / 1024,
+ mts_local.mts_numallocs);
free(str);
for (kmemzonenum = 0, first = 1; ; kmemzonenum++) {
kreado(X_KMEMZONES, &kz, sizeof(kz),
@@ -941,7 +972,7 @@ domem(void)
(void)printf("\n");
break;
}
- if (!(type.ks_size & (1 << kmemzonenum)))
+ if (!(mts_local.mts_size & (1 << kmemzonenum)))
continue;
if (first)
(void)printf(" ");
OpenPOWER on IntegriCloud