summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_malloc.c
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>2008-05-23 00:43:36 +0000
committerjb <jb@FreeBSD.org>2008-05-23 00:43:36 +0000
commit8c4eed9aad5a7911341733c7a8d074c9fd9e11f1 (patch)
treec58a457140c1901b19f4699c2f53851074e7405d /sys/kern/kern_malloc.c
parentb64f9e972e44459a0eea5a3726f39f8f7e716956 (diff)
downloadFreeBSD-src-8c4eed9aad5a7911341733c7a8d074c9fd9e11f1.zip
FreeBSD-src-8c4eed9aad5a7911341733c7a8d074c9fd9e11f1.tar.gz
Add support for the DTrace malloc provider which can enable probes
on a per-malloc type basis.
Diffstat (limited to 'sys/kern/kern_malloc.c')
-rw-r--r--sys/kern/kern_malloc.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 8f2b509..3b169d5 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -46,6 +46,7 @@
__FBSDID("$FreeBSD$");
#include "opt_ddb.h"
+#include "opt_kdtrace.h"
#include "opt_vm.h"
#include <sys/param.h>
@@ -86,6 +87,12 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+dtrace_malloc_probe_func_t dtrace_malloc_probe;
+#endif
+
/*
* When realloc() is called, if the new size is sufficiently smaller than
* the old size, realloc() will allocate a new, smaller block to avoid
@@ -255,6 +262,17 @@ malloc_type_zone_allocated(struct malloc_type *mtp, unsigned long size,
}
if (zindx != -1)
mtsp->mts_size |= 1 << zindx;
+
+#ifdef KDTRACE_HOOKS
+ if (dtrace_malloc_probe != NULL) {
+ uint32_t probe_id = mtip->mti_probes[DTMALLOC_PROBE_MALLOC];
+ if (probe_id != 0)
+ (dtrace_malloc_probe)(probe_id,
+ (uintptr_t) mtp, (uintptr_t) mtip,
+ (uintptr_t) mtsp, size, zindx);
+ }
+#endif
+
critical_exit();
}
@@ -283,6 +301,17 @@ malloc_type_freed(struct malloc_type *mtp, unsigned long size)
mtsp = &mtip->mti_stats[curcpu];
mtsp->mts_memfreed += size;
mtsp->mts_numfrees++;
+
+#ifdef KDTRACE_HOOKS
+ if (dtrace_malloc_probe != NULL) {
+ uint32_t probe_id = mtip->mti_probes[DTMALLOC_PROBE_FREE];
+ if (probe_id != 0)
+ (dtrace_malloc_probe)(probe_id,
+ (uintptr_t) mtp, (uintptr_t) mtip,
+ (uintptr_t) mtsp, size, 0);
+ }
+#endif
+
critical_exit();
}
@@ -804,6 +833,40 @@ SYSCTL_PROC(_kern, OID_AUTO, malloc_stats, CTLFLAG_RD|CTLTYPE_STRUCT,
SYSCTL_INT(_kern, OID_AUTO, malloc_count, CTLFLAG_RD, &kmemcount, 0,
"Count of kernel malloc types");
+void
+malloc_type_list(malloc_type_list_func_t *func, void *arg)
+{
+ struct malloc_type *mtp, **bufmtp;
+ int count, i;
+ size_t buflen;
+
+ mtx_lock(&malloc_mtx);
+restart:
+ mtx_assert(&malloc_mtx, MA_OWNED);
+ count = kmemcount;
+ mtx_unlock(&malloc_mtx);
+
+ buflen = sizeof(struct malloc_type *) * count;
+ bufmtp = malloc(buflen, M_TEMP, M_WAITOK);
+
+ mtx_lock(&malloc_mtx);
+
+ if (count < kmemcount) {
+ free(bufmtp, M_TEMP);
+ goto restart;
+ }
+
+ for (mtp = kmemstatistics, i = 0; mtp != NULL; mtp = mtp->ks_next, i++)
+ bufmtp[i] = mtp;
+
+ mtx_unlock(&malloc_mtx);
+
+ for (i = 0; i < count; i++)
+ (func)(bufmtp[i], arg);
+
+ free(bufmtp, M_TEMP);
+}
+
#ifdef DDB
DB_SHOW_COMMAND(malloc, db_show_malloc)
{
OpenPOWER on IntegriCloud