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