From 5e914b96b96b0de11225fc3f93e83a6741f41c6a Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Mon, 15 Apr 2002 05:24:01 +0000 Subject: [PATCH] Finish adding support code for sysctl kern.mprof. This dumps some malloc information related to bucket size effeciency. Three things are printed on each row: Size is the size the user actually asked for rounded to 16 bytes. Requests is the number of times this size was asked for. Real Size is the size we actually handed out. At the end the total memory used and total waste is displayed. Currently my system displays about 33% wasted memory. The intent of this code is to gather statistics for tuning the malloc bucket sizes. It is not intended to be run with INVARIANTS and it is not entirely mp safe. It can be enabled via 'options MALLOC_PROFILE' which was commited earlier. --- sys/kern/kern_malloc.c | 79 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index 592e066c077f..ac8ed513b251 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -90,15 +90,10 @@ static char *kmemlimit; #define KMEM_ZBASE 16 #define KMEM_ZMASK (KMEM_ZBASE - 1) -#define KMEM_ZMAX 65536 +#define KMEM_ZMAX 8192 #define KMEM_ZSIZE (KMEM_ZMAX >> KMEM_ZSHIFT) static u_int8_t kmemsize[KMEM_ZSIZE + 1]; -#ifdef MALLOC_PROFILE -uint64_t krequests[KMEM_ZSIZE + 1]; -#endif - - /* These won't be powers of two for long */ struct { int kz_size; @@ -115,17 +110,19 @@ struct { {2048, "2048", NULL}, {4096, "4096", NULL}, {8192, "8192", NULL}, - {16384, "16384", NULL}, - {32768, "32768", NULL}, - {65536, "65536", NULL}, {0, NULL}, }; u_int vm_kmem_size; static struct mtx malloc_mtx; -static int sysctl_kern_malloc(SYSCTL_HANDLER_ARGS); +#ifdef MALLOC_PROFILE +uint64_t krequests[KMEM_ZSIZE + 1]; +static int sysctl_kern_mprof(SYSCTL_HANDLER_ARGS); +#endif + +static int sysctl_kern_malloc(SYSCTL_HANDLER_ARGS); /* * malloc: @@ -481,7 +478,7 @@ sysctl_kern_malloc(SYSCTL_HANDLER_ARGS) p += len; first = 1; - for (i = 0; i < 14/* 8 * sizeof(type->ks_size)*/; i++) + for (i = 0; i < 8 * sizeof(type->ks_size); i++) if (type->ks_size & (1 << i)) { if (first) len = snprintf(p, curline, " "); @@ -511,3 +508,63 @@ sysctl_kern_malloc(SYSCTL_HANDLER_ARGS) SYSCTL_OID(_kern, OID_AUTO, malloc, CTLTYPE_STRING|CTLFLAG_RD, NULL, 0, sysctl_kern_malloc, "A", "Malloc Stats"); + +#ifdef MALLOC_PROFILE + +static int +sysctl_kern_mprof(SYSCTL_HANDLER_ARGS) +{ + int linesize = 64; + uint64_t count; + uint64_t waste; + uint64_t mem; + int bufsize; + int error; + char *buf; + int rsize; + int size; + char *p; + int len; + int i; + + bufsize = linesize * (KMEM_ZSIZE + 1); + bufsize += 128; /* For the stats line */ + bufsize += 128; /* For the banner line */ + waste = 0; + mem = 0; + + p = buf = (char *)malloc(bufsize, M_TEMP, M_WAITOK|M_ZERO); + len = snprintf(p, bufsize, + "\n Size Requests Real Size\n"); + bufsize -= len; + p += len; + + for (i = 0; i < KMEM_ZSIZE; i++) { + size = i << KMEM_ZSHIFT; + rsize = kmemzones[kmemsize[i]].kz_size; + count = (long long unsigned)krequests[i]; + + len = snprintf(p, bufsize, "%6d%28llu%11d\n", + size, (unsigned long long)count, rsize); + bufsize -= len; + p += len; + + if ((rsize * count) > (size * count)) + waste += (rsize * count) - (size * count); + mem += (rsize * count); + } + + len = snprintf(p, bufsize, + "\nTotal memory used:\t%30llu\nTotal Memory wasted:\t%30llu\n", + (unsigned long long)mem, (unsigned long long)waste); + p += len; + + error = SYSCTL_OUT(req, buf, p - buf); + + free(buf, M_TEMP); + return (error); +} + +SYSCTL_OID(_kern, OID_AUTO, mprof, CTLTYPE_STRING|CTLFLAG_RD, + NULL, 0, sysctl_kern_mprof, "A", "Malloc Profiling"); +#endif /* MALLOC_PROFILE */