tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Extend "struct malloc_type" for extended KMEMSTATS?



Hi,

while trying to get more info on the suspected kernel malloc leak
documented in PR#39145, I found it useful to see how many
allocations of each size each malloc type is currently holding.

The diff attached below implements this functionality, by adding
32 u_long's to "struct malloc_type", and when KMEMSTATS is
enabled, it counts allocations and frees to each power-of-two
size accordingly.  "vmstat -m" can then now show:


Memory statistics by type                                Type  Kern
           Type InUse  MemUse HighUse   Limit   Requests Limit Limit Size(s)
   kernfs mount     1      1K      1K  78644K          1     0     0 16:1
    ptyfs mount     1      1K      1K  78644K          1     0     0 16:1
     prop array     1      1K      1K  78644K          1     0     0 64:1
prop dictionary   145     19K     19K  78644K        145     0     0 128:145
    prop string   143      3K      3K  78644K        143     0     0 16:143
           acpi    30      1K      1K  78644K         31     0     0 
16:7,32:19,64:4
            USB    46      5K      5K  78644K         52     0     0 
16:6,32:6,64:19,128:9,256:6,1024:0
     USB device    18     19K     19K  78644K         18     0     0 
16:6,128:3,2048:9


etc. etc.

Any comments to me adding this change?  Does this warrant a
kernel version bump because malloc_type changes size?

Best regards,

- Håvard
Index: sys/sys/mallocvar.h
===================================================================
RCS file: /u/nb/src/sys/sys/mallocvar.h,v
retrieving revision 1.7
diff -u -r1.7 mallocvar.h
--- sys/sys/mallocvar.h 7 Nov 2007 16:12:25 -0000       1.7
+++ sys/sys/mallocvar.h 16 Jul 2008 14:04:39 -0000
@@ -57,6 +57,7 @@
        u_long  ks_limit;       /* most that are allowed to exist */
        u_long  ks_size;        /* sizes of this thing that are allocated */
        u_long  ks_spare;
+       u_long  ks_active[32];  /* number of active allocations per size */
 };
 
 #ifdef _KERNEL
Index: sys/kern/kern_malloc.c
===================================================================
RCS file: /u/nb/src/sys/kern/kern_malloc.c,v
retrieving revision 1.119
diff -u -r1.119 kern_malloc.c
--- sys/kern/kern_malloc.c      17 Mar 2008 17:05:54 -0000      1.119
+++ sys/kern/kern_malloc.c      16 Jul 2008 14:04:39 -0000
@@ -353,6 +353,7 @@
                        &malloc_lock);
        }
        ksp->ks_size |= 1 << indx;
+       ksp->ks_active[indx]++;
 #endif
 #ifdef DIAGNOSTIC
        copysize = 1 << indx < MAX_COPY ? 1 << indx : MAX_COPY;
@@ -586,6 +587,7 @@
 #ifdef KMEMSTATS
                size = kup->ku_pagecnt << PGSHIFT;
                ksp->ks_memuse -= size;
+               ksp->ks_active[kup->ku_indx]--;
                kup->ku_indx = 0;
                kup->ku_pagecnt = 0;
                if (ksp->ks_memuse + size >= ksp->ks_limit &&
@@ -642,6 +644,7 @@
        }
        kbp->kb_totalfree++;
        ksp->ks_memuse -= size;
+       ksp->ks_active[kup->ku_indx]--;
        if (ksp->ks_memuse + size >= ksp->ks_limit &&
            ksp->ks_memuse < ksp->ks_limit)
                wakeup((void *)ksp);
Index: usr.bin/vmstat/vmstat.c
===================================================================
RCS file: /u/nb/src/usr.bin/vmstat/vmstat.c,v
retrieving revision 1.160
diff -u -r1.160 vmstat.c
--- usr.bin/vmstat/vmstat.c     24 Jun 2008 12:47:23 -0000      1.160
+++ usr.bin/vmstat/vmstat.c     16 Jul 2008 14:04:39 -0000
@@ -1150,14 +1150,19 @@
                    howmany(ks.ks_limit, KILO), ks.ks_calls,
                    ks.ks_limblocks, ks.ks_mapblocks);
                first = 1;
-               for (j =  1 << MINBUCKET; j < 1 << (MINBUCKET + 16); j <<= 1) {
+               for (j =  1 << MINBUCKET, i = MINBUCKET;
+                    j < 1 << (MINBUCKET + 16);
+                    j <<= 1, i++)
+               {
                        if ((ks.ks_size & j) == 0)
                                continue;
                        if (first)
-                               (void)printf(" %d", j);
+                               putchar(' ');
                        else
-                               (void)printf(",%d", j);
+                               putchar(',');
+                       (void)printf("%d", j);
                        first = 0;
+                       (void)printf(":%lu", ks.ks_active[i]);
                }
                (void)printf("\n");
                totuse += ks.ks_memuse;


Home | Main Index | Thread Index | Old Index