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 */
 };

 /*

Reply via email to