Hi, This patch adds additional informational to ddb's "show malloc" command about the largest consumers of memory.
This is my first patch for OpenBSD, so I will be very grateful for any comments. Thanks in advance! Index: sys/kern/kern_malloc.c =================================================================== RCS file: /cvs/src/sys/kern/kern_malloc.c,v retrieving revision 1.128 diff -u -p -r1.128 kern_malloc.c --- sys/kern/kern_malloc.c 14 Mar 2015 03:38:50 -0000 1.128 +++ sys/kern/kern_malloc.c 9 Dec 2015 16:50:57 -0000 @@ -158,6 +158,8 @@ malloc(size_t size, int type, int flags) char *savedtype; #endif #ifdef KMEMSTATS + int i; + struct ktopcount *kftop; struct kmemstats *ksp = &kmemstats[type]; if (((unsigned long)type) <= 1 || ((unsigned long)type) >= M_LAST) @@ -338,6 +340,29 @@ out: ksp->ks_calls++; if (ksp->ks_memuse > ksp->ks_maxused) ksp->ks_maxused = ksp->ks_memuse; + + void *from = __builtin_return_address(0); + from = __builtin_extract_return_addr(from); + if (!from) + goto topout; + + kftop = &ksp->ks_top[0]; + for (i = 0; i < KMEMSTATS_TOPCOUNT; ++i) + { + if (ksp->ks_top[i].kt_from == from) { + ksp->ks_top[i].kt_calls++; + ksp->ks_top[i].kt_memuse += allocsize; + goto topout; + } + else if (ksp->ks_top[i].kt_memuse < kftop->kt_memuse) + kftop = &ksp->ks_top[i]; + } + + kftop->kt_calls = 1; + kftop->kt_memuse = allocsize; + kftop->kt_from = from; + +topout: #else out: #endif @@ -669,6 +694,7 @@ malloc_roundup(size_t sz) #if defined(DDB) #include <machine/db_machdep.h> #include <ddb/db_output.h> +#include <ddb/db_sym.h> void malloc_printit( @@ -676,7 +702,7 @@ malloc_printit( { #ifdef KMEMSTATS struct kmemstats *km; - int i; + int i, j; (*pr)("%15s %5s %6s %7s %6s %9s %8s %8s\n", "Type", "InUse", "MemUse", "HighUse", "Limit", "Requests", @@ -689,6 +715,27 @@ malloc_printit( memname[i], km->ks_inuse, km->ks_memuse / 1024, km->ks_maxused / 1024, km->ks_limit / 1024, km->ks_calls, km->ks_limblocks, km->ks_mapblocks); + } + + (*pr)("\n\n%15s %9s %9s\t%s\n", + "Type", "MemUse", "Requests", "Name"); + for (i = 0, km = kmemstats; i < M_LAST; i++, km++) { + if (!km->ks_calls || !memname[i]) + continue; + + for (j = 0; j < KMEMSTATS_TOPCOUNT; j++) { + if (!km->ks_top[j].kt_from) + continue; + + (*pr)("%15s %9ldK %9ld\t", memname[i], + km->ks_top[j].kt_memuse / 1024, + km->ks_top[j].kt_calls); + + db_printsym((db_addr_t) km->ks_top[j].kt_from, + DB_STGY_ANY, pr); + + (*pr)("\n"); + } } #else (*pr)("No KMEMSTATS compiled in\n"); Index: sys/sys/malloc.h =================================================================== RCS file: /cvs/src/sys/sys/malloc.h,v retrieving revision 1.112 diff -u -p -r1.112 malloc.h --- sys/sys/malloc.h 24 Aug 2015 15:33:49 -0000 1.112 +++ sys/sys/malloc.h 9 Dec 2015 16:50:57 -0000 @@ -316,6 +316,15 @@ "DRM", /* 145 M_DRM */ \ } +#define KMEMSTATS_TOPCOUNT 3 + +struct ktopcount +{ + long kt_calls; /* total allocations for this consumer */ + void* kt_from; /* pointer of the requesting function */ + long kt_memuse; /* total memory held in bytes */ +}; + struct kmemstats { long ks_inuse; /* # of packets of this type currently in use */ long ks_calls; /* total packets of this type ever allocated */ @@ -325,7 +334,7 @@ struct kmemstats { long ks_maxused; /* maximum number ever used */ long ks_limit; /* most that are allowed to exist */ long ks_size; /* sizes of this thing that are allocated */ - long ks_spare; + struct ktopcount ks_top[KMEMSTATS_TOPCOUNT];/* top # of memory usage */ }; /*