kern_dtrace.c revision 219028
1179090Sjb/*-
2179090Sjb * Copyright (c) 2007-2008 John Birrell <jb@FreeBSD.org>
3179090Sjb * All rights reserved.
4179090Sjb *
5179090Sjb * Redistribution and use in source and binary forms, with or without
6179090Sjb * modification, are permitted provided that the following conditions
7179090Sjb * are met:
8179090Sjb * 1. Redistributions of source code must retain the above copyright
9179090Sjb *    notice, this list of conditions and the following disclaimer.
10179090Sjb * 2. Redistributions in binary form must reproduce the above copyright
11179090Sjb *    notice, this list of conditions and the following disclaimer in the
12179090Sjb *    documentation and/or other materials provided with the distribution.
13179090Sjb *
14179090Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15179090Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16179090Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17179090Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18179090Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19179090Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20179090Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21179090Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22179090Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23179090Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24179090Sjb * SUCH DAMAGE.
25179090Sjb */
26179090Sjb
27179090Sjb#include <sys/cdefs.h>
28179090Sjb__FBSDID("$FreeBSD: head/sys/kern/kern_dtrace.c 219028 2011-02-25 10:11:01Z netchild $");
29179090Sjb
30179090Sjb#include "opt_kdb.h"
31179090Sjb
32179090Sjb#include <sys/param.h>
33179090Sjb#include <sys/systm.h>
34179090Sjb#include <sys/eventhandler.h>
35179090Sjb#include <sys/kdb.h>
36179090Sjb#include <sys/kernel.h>
37179090Sjb#include <sys/malloc.h>
38179090Sjb#include <sys/proc.h>
39179090Sjb#include <sys/dtrace_bsd.h>
40219028Snetchild#include <sys/sysctl.h>
41179090Sjb
42179090Sjb#define KDTRACE_PROC_SIZE	64
43179090Sjb#define	KDTRACE_THREAD_SIZE	256
44179090Sjb
45219028SnetchildFEATURE(kdtrace_hooks,
46219028Snetchild    "Kernel DTrace hooks which are required to load DTrace kernel modules");
47219028Snetchild
48179090SjbMALLOC_DEFINE(M_KDTRACE, "kdtrace", "DTrace hooks");
49179090Sjb
50179090Sjb/* Return the DTrace process data size compiled in the kernel hooks. */
51179090Sjbsize_t
52179090Sjbkdtrace_proc_size()
53179090Sjb{
54211613Srpaulo
55211613Srpaulo	return (KDTRACE_PROC_SIZE);
56179090Sjb}
57179090Sjb
58179090Sjbstatic void
59179090Sjbkdtrace_proc_ctor(void *arg __unused, struct proc *p)
60179090Sjb{
61179090Sjb
62211614Srpaulo	p->p_dtrace = malloc(KDTRACE_PROC_SIZE, M_KDTRACE, M_WAITOK|M_ZERO);
63179090Sjb}
64179090Sjb
65179090Sjbstatic void
66179090Sjbkdtrace_proc_dtor(void *arg __unused, struct proc *p)
67179090Sjb{
68211613Srpaulo
69179090Sjb	if (p->p_dtrace != NULL) {
70179090Sjb		free(p->p_dtrace, M_KDTRACE);
71179090Sjb		p->p_dtrace = NULL;
72179090Sjb	}
73179090Sjb}
74179090Sjb
75179090Sjb/* Return the DTrace thread data size compiled in the kernel hooks. */
76179090Sjbsize_t
77179090Sjbkdtrace_thread_size()
78179090Sjb{
79211614Srpaulo
80211613Srpaulo	return (KDTRACE_THREAD_SIZE);
81179090Sjb}
82179090Sjb
83179090Sjbstatic void
84179090Sjbkdtrace_thread_ctor(void *arg __unused, struct thread *td)
85179090Sjb{
86179090Sjb
87211614Srpaulo	td->td_dtrace = malloc(KDTRACE_THREAD_SIZE, M_KDTRACE, M_WAITOK|M_ZERO);
88179090Sjb}
89179090Sjb
90179090Sjbstatic void
91179090Sjbkdtrace_thread_dtor(void *arg __unused, struct thread *td)
92179090Sjb{
93211613Srpaulo
94179090Sjb	if (td->td_dtrace != NULL) {
95179090Sjb		free(td->td_dtrace, M_KDTRACE);
96179090Sjb		td->td_dtrace = NULL;
97179090Sjb	}
98179090Sjb}
99179090Sjb
100179090Sjb/*
101179090Sjb *  Initialise the kernel DTrace hooks.
102179090Sjb */
103179090Sjbstatic void
104179090Sjbinit_dtrace(void *dummy __unused)
105179090Sjb{
106211613Srpaulo
107211613Srpaulo	EVENTHANDLER_REGISTER(process_ctor, kdtrace_proc_ctor, NULL,
108211613Srpaulo	    EVENTHANDLER_PRI_ANY);
109211613Srpaulo	EVENTHANDLER_REGISTER(process_dtor, kdtrace_proc_dtor, NULL,
110211613Srpaulo	    EVENTHANDLER_PRI_ANY);
111211613Srpaulo	EVENTHANDLER_REGISTER(thread_ctor, kdtrace_thread_ctor, NULL,
112211613Srpaulo	    EVENTHANDLER_PRI_ANY);
113211613Srpaulo	EVENTHANDLER_REGISTER(thread_dtor, kdtrace_thread_dtor, NULL,
114211613Srpaulo	    EVENTHANDLER_PRI_ANY);
115179090Sjb}
116179090Sjb
117179090SjbSYSINIT(kdtrace, SI_SUB_KDTRACE, SI_ORDER_FIRST, init_dtrace, NULL);
118