From 8e73022ddaefea63bff25250543662de5caa2c1c Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 Jul 2005 22:35:10 +0000 Subject: [PATCH] Teach vmstat -m and vmstat -z to use libmemstat(3). Certain statistics from -z are now a bit different due to changes in the way statistics are now measured. Reproduce with some amount of accuracy the slightly obscure layouts adopted by the two kernel sysctls. In the future, we might want to normalize them. GC dosysctl(), which is now no longer used. MFC after: 1 week --- usr.bin/vmstat/Makefile | 4 +- usr.bin/vmstat/vmstat.c | 115 ++++++++++++++++++++++++++++++++-------- 2 files changed, 96 insertions(+), 23 deletions(-) diff --git a/usr.bin/vmstat/Makefile b/usr.bin/vmstat/Makefile index da2a08da33ee..21795e9ac09f 100644 --- a/usr.bin/vmstat/Makefile +++ b/usr.bin/vmstat/Makefile @@ -3,7 +3,7 @@ PROG= vmstat MAN= vmstat.8 -DPADD= ${LIBDEVSTAT} ${LIBKVM} -LDADD= -ldevstat -lkvm +DPADD= ${LIBDEVSTAT} ${LIBKVM} ${LIBMEMSTAT} +LDADD= -ldevstat -lkvm -lmemstat .include diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index 9ee2c36f24ff..d0eedbe2e67f 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -153,7 +154,6 @@ static void doforkst(void); static void domem(void); static void dointr(void); static void dosum(void); -static void dosysctl(const char *); static void dovmstat(unsigned int, int); static void dozmem(void); static void kread(int, void *, size_t); @@ -897,6 +897,97 @@ dointr(void) (long long)inttotal, (long long)(inttotal / uptime)); } +/* + * Query libmemstat(3) for information on malloc(9). + */ +static void +domemstat_malloc(void) +{ + struct memory_type_list *mtlp; + struct memory_type *mtp; + int first, i; + + mtlp = memstat_mtl_alloc(); + if (mtlp == NULL) { + warn("memstat_mtl_alloc"); + return; + } + + if (memstat_sysctl_malloc(mtlp, 0) < 0) { + warnx("memstat_sysctl_malloc: %s", + memstat_strerror(memstat_mtl_geterror(mtlp))); + return; + } + + printf("\n"); + printf("%13s %5s %6s %7s %8s Size(s)\n", "Type", "InUse", "MemUse", + "HighUse", "Requests"); + + for (mtp = memstat_mtl_first(mtlp); mtp != NULL; + mtp = memstat_mtl_next(mtp)) { + if (memstat_get_numallocs(mtp) == 0 && + memstat_get_count(mtp) == 0) + continue; + printf("%13s %5lld %5lldK %7s %8lld ", + memstat_get_name(mtp), memstat_get_count(mtp), + ((int64_t)memstat_get_bytes(mtp) + 1023) / 1024, "-", + memstat_get_numallocs(mtp)); + + first = 1; + for (i = 0; i < 32; i++) { + if (memstat_get_sizemask(mtp) & (1 << i)) { + if (!first) + printf(","); + printf("%d", 1 << (i + 4)); + first = 0; + } + } + printf("\n"); + } + + memstat_mtl_free(mtlp); +} + +/* + * Query libmemstat(3) for information on uma(9). + */ +static void +domemstat_zone(void) +{ + struct memory_type_list *mtlp; + struct memory_type *mtp; + char name[MEMTYPE_MAXNAME + 1]; + + mtlp = memstat_mtl_alloc(); + if (mtlp == NULL) { + warn("memstat_mtl_alloc"); + return; + } + + if (memstat_sysctl_uma(mtlp, 0) < 0) { + warnx("memstat_sysctl_uma: %s", + memstat_strerror(memstat_mtl_geterror(mtlp))); + return; + } + + printf("\n"); + printf("%-15s %-8s %-9s %-7s %-5s %-8s\n\n", "ITEM", "SIZE", "LIMIT", + "USED", "FREE", "REQUESTS"); + + for (mtp = memstat_mtl_first(mtlp); mtp != NULL; + mtp = memstat_mtl_next(mtp)) { + strlcpy(name, memstat_get_name(mtp), MEMTYPE_MAXNAME); + strcat(name, ":"); + printf("%-15s %4llu, %8llu, %7llu, %6llu, %8llu\n", name, + memstat_get_size(mtp), memstat_get_countlimit(mtp), + memstat_get_count(mtp), memstat_get_free(mtp), + memstat_get_numallocs(mtp)); + } + + memstat_mtl_free(mtlp); + printf("\n"); +} + /* * domem() replicates the kernel implementation of kern.malloc by inspecting * kernel data structures, which is appropriate for use on a core dump. @@ -915,7 +1006,7 @@ domem(void) int i; if (kd == NULL) { - dosysctl("kern.malloc"); + domemstat_malloc(); return; } kread(X_KMEMSTATS, &type.ks_next, sizeof(type.ks_next)); @@ -991,25 +1082,7 @@ dozmem(void) { if (kd != NULL) errx(1, "not implemented"); - dosysctl("vm.zone"); -} - -static void -dosysctl(const char *name) -{ - char *buf; - size_t bufsize; - - for (buf = NULL, bufsize = 1024; ; bufsize *= 2) { - if ((buf = realloc(buf, bufsize)) == NULL) - err(1, "realloc()"); - bufsize--; /* Leave space for the kern.malloc fixup. */ - if (mysysctl(name, buf, &bufsize, NULL, 0) == 0) - break; - } - buf[bufsize] = '\0'; /* Fix up kern.malloc not returning a string. */ - (void)printf("%s", buf); - free(buf); + domemstat_zone(); } /*