tech-kern archive

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

Re: Extend "struct malloc_type" for extended KMEMSTATS?



> 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.

I got some private feedback, and a new diff is attached below.
Changes since the previous one:

 o Many of the fields in struct malloc_type ought to be size_t
   instead of u_long.  A few printf formats had to be adjusted to
   correspond.
 o The "spare" field is deleted.
 o The counters per block size are u_int instead of u_long,
   saving some bytes on lp64 platforms (and again printf formats
   correspondingly adjusted).

I've verified that this still builds correctly for a large number
of ports.

Oh, yes, I also got a comment that a kernel version bump would be
required for this as well.

Further comments?

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 18 Jul 2008 06:53:12 -0000
@@ -48,15 +48,15 @@
        const char *ks_shortdesc;/* short description */
 
        /* Statistics */
-       u_long  ks_inuse;       /* # of packets of this type currently in use */
+       size_t  ks_inuse;       /* # of packets of this type currently in use */
        u_long  ks_calls;       /* total packets of this type ever allocated */
-       u_long  ks_memuse;      /* total memory held in bytes */
+       size_t  ks_memuse;      /* total memory held in bytes */
+       size_t  ks_maxused;     /* maximum number ever used */
+       size_t  ks_limit;       /* most that are allowed to exist */
+       size_t  ks_size;        /* sizes of this thing that are allocated */
        u_short ks_limblocks;   /* number of times blocked for hitting limit */
        u_short ks_mapblocks;   /* number of times blocked for kernel map */
-       u_long  ks_maxused;     /* maximum number ever used */
-       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_int   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      18 Jul 2008 06:53:12 -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);
@@ -946,7 +949,7 @@
        for (ksp = kmemstatistics; ksp != NULL; ksp = ksp->ks_next) {
                if (ksp->ks_memuse == 0)
                        continue;
-               db_printf("%s%.*s %ld\n", ksp->ks_shortdesc,
+               db_printf("%s%.*s %zd\n", ksp->ks_shortdesc,
                    (int)(20 - strlen(ksp->ks_shortdesc)),
                    "                    ",
                    ksp->ks_memuse);
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     18 Jul 2008 06:53:12 -0000
@@ -1143,21 +1143,26 @@
                        continue;
                deref_kptr(ks.ks_shortdesc, memname,
                    sizeof(memname), "malloc type name");
-               (void)printf("%15s %5ld %6ldK %6ldK %6ldK %10ld %5u %5u",
+               (void)printf("%15s %5zd %6zdK %6zdK %6zdK %10ld %5u %5u",
                    memname,
                    ks.ks_inuse, howmany(ks.ks_memuse, KILO),
                    howmany(ks.ks_maxused, KILO),
                    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(":%u", ks.ks_active[i]);
                }
                (void)printf("\n");
                totuse += ks.ks_memuse;


Home | Main Index | Thread Index | Old Index