summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--sys/kern/kern_malloc.c63
-rw-r--r--sys/sys/malloc.h15
2 files changed, 78 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)
{
diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h
index 8ea1887..33b287f 100644
--- a/sys/sys/malloc.h
+++ b/sys/sys/malloc.h
@@ -80,7 +80,16 @@ struct malloc_type_stats {
uint64_t _mts_reserved3; /* Reserved field. */
};
+/*
+ * Index definitions for the mti_probes[] array.
+ */
+#define DTMALLOC_PROBE_MALLOC 0
+#define DTMALLOC_PROBE_FREE 1
+#define DTMALLOC_PROBE_MAX 2
+
struct malloc_type_internal {
+ uint32_t mti_probes[DTMALLOC_PROBE_MAX];
+ /* DTrace probe ID array. */
struct malloc_type_stats mti_stats[MAXCPU];
};
@@ -173,6 +182,11 @@ MALLOC_DECLARE(M_IOV);
extern struct mtx malloc_mtx;
+/*
+ * Function type used when iterating over the list of malloc types.
+ */
+typedef void malloc_type_list_func_t(struct malloc_type *, void *);
+
void contigfree(void *addr, unsigned long size, struct malloc_type *type);
void *contigmalloc(unsigned long size, struct malloc_type *type, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
@@ -183,6 +197,7 @@ void malloc_init(void *);
int malloc_last_fail(void);
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
void malloc_type_freed(struct malloc_type *type, unsigned long size);
+void malloc_type_list(malloc_type_list_func_t *, void *);
void malloc_uninit(void *);
void *realloc(void *addr, unsigned long size, struct malloc_type *type,
int flags);
OpenPOWER on IntegriCloud