180544aebSJohn Birrell /*- 280544aebSJohn Birrell * Copyright (c) 2007-2008 John Birrell <jb@FreeBSD.org> 380544aebSJohn Birrell * All rights reserved. 480544aebSJohn Birrell * 580544aebSJohn Birrell * Redistribution and use in source and binary forms, with or without 680544aebSJohn Birrell * modification, are permitted provided that the following conditions 780544aebSJohn Birrell * are met: 880544aebSJohn Birrell * 1. Redistributions of source code must retain the above copyright 980544aebSJohn Birrell * notice, this list of conditions and the following disclaimer. 1080544aebSJohn Birrell * 2. Redistributions in binary form must reproduce the above copyright 1180544aebSJohn Birrell * notice, this list of conditions and the following disclaimer in the 1280544aebSJohn Birrell * documentation and/or other materials provided with the distribution. 1380544aebSJohn Birrell * 1480544aebSJohn Birrell * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1580544aebSJohn Birrell * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1680544aebSJohn Birrell * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1780544aebSJohn Birrell * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1880544aebSJohn Birrell * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1980544aebSJohn Birrell * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2080544aebSJohn Birrell * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2180544aebSJohn Birrell * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2280544aebSJohn Birrell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2380544aebSJohn Birrell * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2480544aebSJohn Birrell * SUCH DAMAGE. 2580544aebSJohn Birrell */ 2680544aebSJohn Birrell 2780544aebSJohn Birrell #include <sys/cdefs.h> 2880544aebSJohn Birrell __FBSDID("$FreeBSD$"); 2980544aebSJohn Birrell 3080544aebSJohn Birrell #include "opt_kdb.h" 3180544aebSJohn Birrell 3280544aebSJohn Birrell #include <sys/param.h> 3380544aebSJohn Birrell #include <sys/systm.h> 3480544aebSJohn Birrell #include <sys/eventhandler.h> 3580544aebSJohn Birrell #include <sys/kdb.h> 3680544aebSJohn Birrell #include <sys/kernel.h> 3780544aebSJohn Birrell #include <sys/malloc.h> 3880544aebSJohn Birrell #include <sys/proc.h> 3980544aebSJohn Birrell #include <sys/dtrace_bsd.h> 40*de5b1952SAlexander Leidinger #include <sys/sysctl.h> 4180544aebSJohn Birrell 4280544aebSJohn Birrell #define KDTRACE_PROC_SIZE 64 4380544aebSJohn Birrell #define KDTRACE_THREAD_SIZE 256 4480544aebSJohn Birrell 45*de5b1952SAlexander Leidinger FEATURE(kdtrace_hooks, 46*de5b1952SAlexander Leidinger "Kernel DTrace hooks which are required to load DTrace kernel modules"); 47*de5b1952SAlexander Leidinger 4880544aebSJohn Birrell MALLOC_DEFINE(M_KDTRACE, "kdtrace", "DTrace hooks"); 4980544aebSJohn Birrell 5080544aebSJohn Birrell /* Return the DTrace process data size compiled in the kernel hooks. */ 5180544aebSJohn Birrell size_t 5280544aebSJohn Birrell kdtrace_proc_size() 5380544aebSJohn Birrell { 549f3a1843SRui Paulo 5580544aebSJohn Birrell return (KDTRACE_PROC_SIZE); 5680544aebSJohn Birrell } 5780544aebSJohn Birrell 5880544aebSJohn Birrell static void 5980544aebSJohn Birrell kdtrace_proc_ctor(void *arg __unused, struct proc *p) 6080544aebSJohn Birrell { 6180544aebSJohn Birrell 62258f5a25SRui Paulo p->p_dtrace = malloc(KDTRACE_PROC_SIZE, M_KDTRACE, M_WAITOK|M_ZERO); 6380544aebSJohn Birrell } 6480544aebSJohn Birrell 6580544aebSJohn Birrell static void 6680544aebSJohn Birrell kdtrace_proc_dtor(void *arg __unused, struct proc *p) 6780544aebSJohn Birrell { 689f3a1843SRui Paulo 6980544aebSJohn Birrell if (p->p_dtrace != NULL) { 7080544aebSJohn Birrell free(p->p_dtrace, M_KDTRACE); 7180544aebSJohn Birrell p->p_dtrace = NULL; 7280544aebSJohn Birrell } 7380544aebSJohn Birrell } 7480544aebSJohn Birrell 7580544aebSJohn Birrell /* Return the DTrace thread data size compiled in the kernel hooks. */ 7680544aebSJohn Birrell size_t 7780544aebSJohn Birrell kdtrace_thread_size() 7880544aebSJohn Birrell { 79258f5a25SRui Paulo 8080544aebSJohn Birrell return (KDTRACE_THREAD_SIZE); 8180544aebSJohn Birrell } 8280544aebSJohn Birrell 8380544aebSJohn Birrell static void 8480544aebSJohn Birrell kdtrace_thread_ctor(void *arg __unused, struct thread *td) 8580544aebSJohn Birrell { 8680544aebSJohn Birrell 87258f5a25SRui Paulo td->td_dtrace = malloc(KDTRACE_THREAD_SIZE, M_KDTRACE, M_WAITOK|M_ZERO); 8880544aebSJohn Birrell } 8980544aebSJohn Birrell 9080544aebSJohn Birrell static void 9180544aebSJohn Birrell kdtrace_thread_dtor(void *arg __unused, struct thread *td) 9280544aebSJohn Birrell { 939f3a1843SRui Paulo 9480544aebSJohn Birrell if (td->td_dtrace != NULL) { 9580544aebSJohn Birrell free(td->td_dtrace, M_KDTRACE); 9680544aebSJohn Birrell td->td_dtrace = NULL; 9780544aebSJohn Birrell } 9880544aebSJohn Birrell } 9980544aebSJohn Birrell 10080544aebSJohn Birrell /* 10180544aebSJohn Birrell * Initialise the kernel DTrace hooks. 10280544aebSJohn Birrell */ 10380544aebSJohn Birrell static void 10480544aebSJohn Birrell init_dtrace(void *dummy __unused) 10580544aebSJohn Birrell { 1069f3a1843SRui Paulo 1079f3a1843SRui Paulo EVENTHANDLER_REGISTER(process_ctor, kdtrace_proc_ctor, NULL, 1089f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 1099f3a1843SRui Paulo EVENTHANDLER_REGISTER(process_dtor, kdtrace_proc_dtor, NULL, 1109f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 1119f3a1843SRui Paulo EVENTHANDLER_REGISTER(thread_ctor, kdtrace_thread_ctor, NULL, 1129f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 1139f3a1843SRui Paulo EVENTHANDLER_REGISTER(thread_dtor, kdtrace_thread_dtor, NULL, 1149f3a1843SRui Paulo EVENTHANDLER_PRI_ANY); 11580544aebSJohn Birrell } 11680544aebSJohn Birrell 11780544aebSJohn Birrell SYSINIT(kdtrace, SI_SUB_KDTRACE, SI_ORDER_FIRST, init_dtrace, NULL); 118