diff options
author | rwatson <rwatson@FreeBSD.org> | 2005-05-29 13:40:00 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2005-05-29 13:40:00 +0000 |
commit | f5b0199972b5e0563c6ea9ef6319ccf723b596f1 (patch) | |
tree | 0411e9c0a956564d16827de06fe2eb53a7c39596 /usr.bin | |
parent | 7035f9f56aa6a07ac9af727380ff3092b79ee9f7 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | usr.bin/vmstat/vmstat.c | 45 |
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(" "); |