Module Name: src Committed By: darran Date: Mon Mar 1 21:10:19 UTC 2010
Modified Files: src/distrib/sets/lists/modules: mi src/external/cddl/osnet/dev/sdt: sdt.c src/sys/conf: Makefile.kern.inc files src/sys/kern: kern_exec.c kern_exit.c kern_fork.c kern_ksyms.c kern_lwp.c kern_sig.c src/sys/modules/dtrace: Makefile src/sys/sys: Makefile ksyms.h Added Files: src/sys/kern: kern_sdt.c src/sys/modules/dtrace/sdt: Makefile src/sys/sys: sdt.h Log Message: DTrace: Add an SDT (Statically Defined Tracing) provider framework, and implement most of the proc provider. Adds proc:::create, exec, exec_success, exec_faillure, signal_send, signal_discard, signal_handle, lwp_create, lwp_start, lwp_exit. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/distrib/sets/lists/modules/mi cvs rdiff -u -r1.2 -r1.3 src/external/cddl/osnet/dev/sdt/sdt.c cvs rdiff -u -r1.125 -r1.126 src/sys/conf/Makefile.kern.inc cvs rdiff -u -r1.977 -r1.978 src/sys/conf/files cvs rdiff -u -r1.293 -r1.294 src/sys/kern/kern_exec.c cvs rdiff -u -r1.225 -r1.226 src/sys/kern/kern_exit.c cvs rdiff -u -r1.175 -r1.176 src/sys/kern/kern_fork.c cvs rdiff -u -r1.53 -r1.54 src/sys/kern/kern_ksyms.c cvs rdiff -u -r1.140 -r1.141 src/sys/kern/kern_lwp.c cvs rdiff -u -r0 -r1.1 src/sys/kern/kern_sdt.c cvs rdiff -u -r1.302 -r1.303 src/sys/kern/kern_sig.c cvs rdiff -u -r1.1 -r1.2 src/sys/modules/dtrace/Makefile cvs rdiff -u -r0 -r1.1 src/sys/modules/dtrace/sdt/Makefile cvs rdiff -u -r1.125 -r1.126 src/sys/sys/Makefile cvs rdiff -u -r1.23 -r1.24 src/sys/sys/ksyms.h cvs rdiff -u -r0 -r1.1 src/sys/sys/sdt.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/modules/mi diff -u src/distrib/sets/lists/modules/mi:1.7 src/distrib/sets/lists/modules/mi:1.8 --- src/distrib/sets/lists/modules/mi:1.7 Sun Feb 21 03:18:47 2010 +++ src/distrib/sets/lists/modules/mi Mon Mar 1 21:10:19 2010 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.7 2010/02/21 03:18:47 darran Exp $ +# $NetBSD: mi,v 1.8 2010/03/01 21:10:19 darran Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -92,6 +92,8 @@ ./@MODULEDIR@/puffs/puffs.kmod base-kernel-modules kmod ./@MODULEDIR@/putter base-kernel-modules kmod ./@MODULEDIR@/putter/putter.kmod base-kernel-modules kmod +./@MODULEDIR@/sdt base-kernel-modules kmod,dtrace +./@MODULEDIR@/sdt/sdt.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/secmodel_bsd44 base-kernel-modules kmod ./@MODULEDIR@/secmodel_bsd44/secmodel_bsd44.kmod base-kernel-modules kmod ./@MODULEDIR@/secmodel_overlay base-kernel-modules kmod @@ -100,8 +102,8 @@ ./@MODULEDIR@/securelevel/securelevel.kmod base-kernel-modules kmod ./@MODULEDIR@/smbfs base-kernel-modules kmod ./@MODULEDIR@/smbfs/smbfs.kmod base-kernel-modules kmod -./@MODULEDIR@/solaris base-kernel-modules kmod,zfs -./@MODULEDIR@/solaris/solaris.kmod base-kernel-modules kmod,zfs +./@MODULEDIR@/solaris base-kernel-modules kmod,dtrace +./@MODULEDIR@/solaris/solaris.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/suser base-kernel-modules kmod ./@MODULEDIR@/suser/suser.kmod base-kernel-modules kmod ./@MODULEDIR@/sysvbfs base-kernel-modules kmod Index: src/external/cddl/osnet/dev/sdt/sdt.c diff -u src/external/cddl/osnet/dev/sdt/sdt.c:1.2 src/external/cddl/osnet/dev/sdt/sdt.c:1.3 --- src/external/cddl/osnet/dev/sdt/sdt.c:1.2 Sun Feb 21 01:46:33 2010 +++ src/external/cddl/osnet/dev/sdt/sdt.c Mon Mar 1 21:10:19 2010 @@ -1,33 +1,38 @@ -/* $NetBSD: sdt.c,v 1.2 2010/02/21 01:46:33 darran Exp $ */ +/* $NetBSD: sdt.c,v 1.3 2010/03/01 21:10:19 darran Exp $ */ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] + * This code is derived from software contributed to The NetBSD Foundation + * by CoyotePoint Systems, Inc. It was developed under contract to + * CoyotePoint by Darran Hunt. * - * CDDL HEADER END + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Portions Copyright 2006-2008 John Birrell j...@freebsd.org - * - * $FreeBSD: src/sys/cddl/dev/sdt/sdt.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $ * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef KDTRACE_HOOKS -#define KDTRACE_HOOKS +#ifdef _KERNEL_OPT +#include "opt_dtrace.h" #endif #include <sys/cdefs.h> @@ -35,42 +40,34 @@ #include <sys/systm.h> #include <sys/conf.h> #include <sys/kernel.h> -#include <sys/limits.h> -#include <sys/lock.h> -#include <sys/linker.h> #include <sys/module.h> #include <sys/mutex.h> #include <sys/dtrace.h> + +#define KDTRACE_HOOKS #include <sys/sdt.h> -#define SDT_ADDR2NDX(addr) (((uintptr_t)(addr)) >> 4) +#undef SDT_DEBUG + +static dev_type_open(sdt_open); -static d_open_t sdt_open; static int sdt_unload(void); static void sdt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *); -static void sdt_provide_probes(void *, dtrace_probedesc_t *); +static void sdt_provide(void *, dtrace_probedesc_t *); static void sdt_destroy(void *, dtrace_id_t, void *); static void sdt_enable(void *, dtrace_id_t, void *); static void sdt_disable(void *, dtrace_id_t, void *); static void sdt_load(void *); -static struct cdevsw sdt_cdevsw = { - .d_version = D_VERSION, - .d_open = sdt_open, - .d_name = "sdt", -}; - -static dtrace_pattr_t sdt_attr = { -{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, -{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, -{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, -{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, -{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, +static const struct cdevsw sdt_cdevsw = { + sdt_open, noclose, noread, nowrite, noioctl, + nostop, notty, nopoll, nommap, nokqfilter, + D_OTHER }; static dtrace_pops_t sdt_pops = { - sdt_provide_probes, + sdt_provide, NULL, sdt_enable, sdt_disable, @@ -84,173 +81,396 @@ static struct cdev *sdt_cdev; -static int -sdt_argtype_callback(struct sdt_argtype *argtype, void *arg) -{ - dtrace_argdesc_t *desc = arg; +/* + * Provider and probe definitions + */ - if (desc->dtargd_ndx == argtype->ndx) { - desc->dtargd_mapping = desc->dtargd_ndx; /* XXX */ - strlcpy(desc->dtargd_native, argtype->type, - sizeof(desc->dtargd_native)); - desc->dtargd_xlate[0] = '\0'; /* XXX */ - } +/* + * proc provider + */ - return (0); -} +/* declare all probes belonging to the provider */ +SDT_PROBE_DECLARE(proc,,,create); +SDT_PROBE_DECLARE(proc,,,exec); +SDT_PROBE_DECLARE(proc,,,exec_success); +SDT_PROBE_DECLARE(proc,,,exec_failure); +SDT_PROBE_DECLARE(proc,,,signal_send); +SDT_PROBE_DECLARE(proc,,,signal_discard); +SDT_PROBE_DECLARE(proc,,,signal_clear); +SDT_PROBE_DECLARE(proc,,,signal_handle); +SDT_PROBE_DECLARE(proc,,,lwp_create); +SDT_PROBE_DECLARE(proc,,,lwp_start); +SDT_PROBE_DECLARE(proc,,,lwp_exit); + +/* define the provider */ +static sdt_provider_t l7_provider = { + "proc", /* provider name */ + 0, /* registered ID - leave as 0 */ + { + { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, + { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, + { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, + { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, + { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, + }, + + /* list all probes belonging to the provider */ + { + &SDT_NAME(proc,,,create), + &SDT_NAME(proc,,,exec), + &SDT_NAME(proc,,,exec_success), + &SDT_NAME(proc,,,exec_failure), + &SDT_NAME(proc,,,signal_send), + &SDT_NAME(proc,,,signal_discard), + &SDT_NAME(proc,,,signal_clear), + &SDT_NAME(proc,,,signal_handle), + &SDT_NAME(proc,,,lwp_create), + &SDT_NAME(proc,,,lwp_start), + &SDT_NAME(proc,,,lwp_exit), + NULL /* NULL terminated list */ + } +}; + +/* list of local providers to register with DTrace */ +static sdt_provider_t *sdt_providers[] = { + &l7_provider, + NULL /* NULL terminated list */ +}; + +static sdt_provider_t **sdt_list = NULL; /* registered provider list */ +static kmutex_t sdt_mutex; +static int sdt_count = 0; /* number of registered providers */ static void sdt_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc) { - struct sdt_probe *probe = parg; + sdt_provider_t *sprov = arg; + sdt_probe_t *sprobe = parg; + int res; + int ind; + +#ifdef SDT_DEBUG + printf("sdt: %s probe %d\n", __func__, id); + printf("%s: probe %d (%s:%s:%s:%s).%d\n", + __func__, id, + sprobe->provider, + sprobe->module, + sprobe->function, + sprobe->name, + desc->dtargd_ndx); +#endif - if (desc->dtargd_ndx < probe->n_args) - (void) (sdt_argtype_listall(probe, sdt_argtype_callback, desc)); - else + /* provide up to 5 arguments */ + if ((desc->dtargd_ndx < SDT_MAX_ARGS) && + (sprobe->argv[desc->dtargd_ndx] != NULL)) { + strncpy(desc->dtargd_native, sprobe->argv[desc->dtargd_ndx], + sizeof(desc->dtargd_native)); + desc->dtargd_mapping = desc->dtargd_ndx; + if (sprobe->argx[desc->dtargd_ndx] != NULL) { + strncpy(desc->dtargd_xlate, sprobe->argx[desc->dtargd_ndx], + sizeof(desc->dtargd_xlate)); + } +#ifdef SDT_DEBUG + printf("%s: probe %d (%s:%s:%s:%s).%d = %s\n", + __func__, id, + sprobe->provider, + sprobe->module, + sprobe->function, + sprobe->name, + desc->dtargd_ndx, + sprobe->argv[desc->dtargd_ndx]); +#endif + } else { +#ifdef SDT_DEBUG + printf("%s: probe %d (%s:%s:%s:%s).%d = NULL\n", + __func__, id, + sprobe->provider, + sprobe->module, + sprobe->function, + sprobe->name, + desc->dtargd_ndx); desc->dtargd_ndx = DTRACE_ARGNONE; - - return; +#endif + } } -static int -sdt_probe_callback(struct sdt_probe *probe, void *arg __unused) +static void +sdt_provide(void *arg, dtrace_probedesc_t *desc) { - struct sdt_provider *prov = probe->prov; - char mod[64]; - char func[64]; - char name[64]; - - /* - * Unfortunately this is necessary because the Solaris DTrace - * code mixes consts and non-consts with casts to override - * the incompatibilies. On FreeBSD, we use strict warnings - * in gcc, so we have to respect const vs non-const. - */ - strlcpy(mod, probe->mod, sizeof(mod)); - strlcpy(func, probe->func, sizeof(func)); - strlcpy(name, probe->name, sizeof(name)); - - if (dtrace_probe_lookup(prov->id, mod, func, name) != 0) - return (0); + sdt_provider_t *sprov = arg; + int res; + int ind; + int num_probes=0; + +#ifdef SDT_DEBUG + if (desc == NULL) { + printf("sdt: provide null\n"); + } else { + printf("sdt: provide %d %02x:%02x:%02x:%02x\n", + desc->dtpd_id, + desc->dtpd_provider[0], + desc->dtpd_mod[0], + desc->dtpd_func[0], + desc->dtpd_name[0]); + } +#endif - (void) dtrace_probe_create(prov->id, probe->mod, probe->func, - probe->name, 0, probe); + for (ind=0; sprov->probes[ind] != NULL; ind++) { + if (sprov->probes[ind]->created == 0) { + res = dtrace_probe_create(sprov->id, + sprov->probes[ind]->module, + sprov->probes[ind]->function, + sprov->probes[ind]->name, + 0, sprov->probes[ind]); + sprov->probes[ind]->id = res; +#ifdef SDT_DEBUG + printf("%s: dtrace_probe_create[%d] res=%d\n", + __func__, ind, res); +#endif + sprov->probes[ind]->created = 1; + num_probes++; + } + } - return (0); -} +#ifdef SDT_DEBUG + printf("sdt: %s num_probes %d\n", __func__, ind); +#endif -static int -sdt_provider_entry(struct sdt_provider *prov, void *arg) -{ - return (sdt_probe_listall(prov, sdt_probe_callback, NULL)); } static void -sdt_provide_probes(void *arg, dtrace_probedesc_t *desc) +sdt_destroy(void *arg, dtrace_id_t id, void *parg) { - if (desc != NULL) - return; + sdt_provider_t *sprov = arg; + int ind; - (void) sdt_provider_listall(sdt_provider_entry, NULL); -} +#ifdef SDT_DEBUG + printf("sdt: %s\n", __func__); +#endif -static void -sdt_destroy(void *arg, dtrace_id_t id, void *parg) -{ - /* Nothing to do here. */ + for (ind=0; sprov->probes[ind] != NULL; ind++) { + if (sprov->probes[ind]->id == id) { +#ifdef SDT_DEBUG + printf("%s: destroying probe %d (%s:%s:%s:%s)\n", + __func__, id, + sprov->probes[ind]->provider, + sprov->probes[ind]->module, + sprov->probes[ind]->function, + sprov->probes[ind]->name); +#endif + sprov->probes[ind]->enabled = 0; + sprov->probes[ind]->created = 0; + sprov->probes[ind]->id = 0; + break; + } + } } static void sdt_enable(void *arg, dtrace_id_t id, void *parg) { - struct sdt_probe *probe = parg; + sdt_provider_t *sprov = arg; + int ind; + +#ifdef SDT_DEBUG + printf("sdt: %s\n", __func__); +#endif - probe->id = id; + for (ind=0; sprov->probes[ind] != NULL; ind++) { + if (sprov->probes[ind]->id == id) { +#ifdef SDT_DEBUG + printf("%s: enabling probe %d (%s:%s:%s:%s)\n", + __func__, id, + sprov->probes[ind]->provider, + sprov->probes[ind]->module, + sprov->probes[ind]->function, + sprov->probes[ind]->name); +#endif + sprov->probes[ind]->enabled = 1; + break; + } + } } static void sdt_disable(void *arg, dtrace_id_t id, void *parg) { - struct sdt_probe *probe = parg; + sdt_provider_t *sprov = arg; + int ind; - probe->id = 0; +#ifdef SDT_DEBUG + printf("sdt: %s\n", __func__); +#endif + + for (ind=0; sprov->probes[ind] != NULL; ind++) { + if (sprov->probes[ind]->id == id) { +#ifdef SDT_DEBUG + printf("%s: disabling probe %d (%s:%s:%s:%s)\n", + __func__, id, + sprov->probes[ind]->provider, + sprov->probes[ind]->module, + sprov->probes[ind]->function, + sprov->probes[ind]->name); +#endif + sprov->probes[ind]->enabled = 0; + break; + } + } } -static int -sdt_provider_reg_callback(struct sdt_provider *prov, void *arg __unused) +int +sdt_register(sdt_provider_t *prov) { - return (dtrace_register(prov->name, &sdt_attr, DTRACE_PRIV_USER, - NULL, &sdt_pops, NULL, (dtrace_provider_id_t *) &prov->id)); + int ind; + int res; + + /* make sure the provider is not already registered */ + for (ind=0; ind < sdt_count; ind++) { + if (strncmp(sdt_list[ind]->name, prov->name, + SDT_MAX_NAME_SIZE) == 0) { + printf("sdt: provider %s already registered\n", prov->name); + return -1; + } + } + + /* register the new provider */ + if ((res = dtrace_register(prov->name, + &prov->attr, DTRACE_PRIV_USER, + NULL, &sdt_pops, prov, + &(prov->id))) != 0) { + printf("sdt: failed to register %s res = %d\n", + prov->name, res); + return -1; + } + + sdt_list[sdt_count++] = prov; + + return 0; } -static void -sdt_load(void *dummy) +int +sdt_unregister(sdt_provider_t *prov) { - /* Create the /dev/dtrace/sdt entry. */ - sdt_cdev = make_dev(&sdt_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, - "dtrace/sdt"); + int ind; + int res; + + /* find the provider reference */ + for (ind=0; ind < sdt_count; ind++) { + if (sdt_list[ind] == prov) { + res = dtrace_unregister(sdt_list[ind]->id); + if (res != 0) { + printf( + "sdt: failed to unregister provider %s\n", + sdt_list[ind]->name); + } + /* remove provider from list */ + sdt_list[ind] = sdt_list[--sdt_count]; + return 0;; + } + } - sdt_probe_func = dtrace_probe; + /* provider not found */ + printf("sdt: provider %s not found\n", prov->name); - (void) sdt_provider_listall(sdt_provider_reg_callback, NULL); + return 0; } -static int -sdt_provider_unreg_callback(struct sdt_provider *prov, void *arg __unused) +static void +sdt_load(void *dummy) { - return (dtrace_unregister(prov->id)); + int ind; + int res; + +#ifdef SDT_DEBUG + printf("sdt: %s\n", __func__); +#endif + + sdt_init(dtrace_probe); + + sdt_list = (sdt_provider_t **)kmem_alloc( + sizeof(sdt_provider_t *) * SDT_MAX_PROVIDER); + + mutex_init(&sdt_mutex, "sdt_mutex", MUTEX_DEFAULT, NULL); + + sdt_count = 0; + + if (sdt_list == NULL) { + printf("sdt: failed to alloc provider list\n"); + return; + } + + for (ind=0; sdt_providers[ind] != NULL; ind++) { + if (sdt_count >= SDT_MAX_PROVIDER) { + printf("sdt: too many providers\n"); + break; + } + sdt_register(sdt_providers[ind]); + +#ifdef SDT_DEBUG + printf("sdt: registered %s id = 0x%x\n", + sdt_providers[ind]->name, + sdt_providers[ind]->id); +#endif + } } + static int sdt_unload() { int error = 0; + int res = 0; + int ind; - sdt_probe_func = sdt_probe_stub; +#ifdef SDT_DEBUG + printf("sdt: %s\n", __func__); +#endif - (void) sdt_provider_listall(sdt_provider_unreg_callback, NULL); - - destroy_dev(sdt_cdev); + for (ind=0; ind < sdt_count; ind++) { + if ((res = dtrace_unregister(sdt_list[ind]->id)) != 0) { +#ifdef SDT_DEBUG + printf("%s: failed to unregister %s error = %d\n", + sdt_list[ind]->name, res); +#endif + error = res; + } else { +#ifdef SDT_DEBUG + printf("sdt: unregistered %s id = %d\n", + sdt_list[ind]->name, + sdt_list[ind]->id); +#endif + } + } + kmem_free(sdt_list, sizeof(sdt_provider_t *) * SDT_MAX_PROVIDER); + mutex_destroy(&sdt_mutex); + sdt_exit(); return (error); } -/* ARGSUSED */ static int -sdt_modevent(module_t mod __unused, int type, void *data __unused) +sdt_modcmd(modcmd_t cmd, void *data) { + int bmajor = -1, cmajor = -1; int error = 0; - switch (type) { - case MOD_LOAD: - break; - - case MOD_UNLOAD: - break; - - case MOD_SHUTDOWN: - break; - + switch (cmd) { + case MODULE_CMD_INIT: + sdt_load(NULL); + return devsw_attach("sdt", NULL, &bmajor, + &sdt_cdevsw, &cmajor); + case MODULE_CMD_FINI: + sdt_unload(); + return devsw_detach(NULL, &sdt_cdevsw); default: - error = EOPNOTSUPP; - break; - + return ENOTTY; } - - return (error); } -/* ARGSUSED */ static int -sdt_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused) +sdt_open(dev_t dev, int flags, int mode, struct lwp *l) { return (0); } -SYSINIT(sdt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, sdt_load, NULL); -SYSUNINIT(sdt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, sdt_unload, NULL); - -DEV_MODULE(sdt, sdt_modevent, NULL); -MODULE_VERSION(sdt, 1); -MODULE_DEPEND(sdt, dtrace, 1, 1, 1); -MODULE_DEPEND(sdt, opensolaris, 1, 1, 1); +MODULE(MODULE_CLASS_MISC, sdt, NULL); Index: src/sys/conf/Makefile.kern.inc diff -u src/sys/conf/Makefile.kern.inc:1.125 src/sys/conf/Makefile.kern.inc:1.126 --- src/sys/conf/Makefile.kern.inc:1.125 Tue Nov 10 20:24:50 2009 +++ src/sys/conf/Makefile.kern.inc Mon Mar 1 21:10:14 2010 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.kern.inc,v 1.125 2009/11/10 20:24:50 tron Exp $ +# $NetBSD: Makefile.kern.inc,v 1.126 2010/03/01 21:10:14 darran Exp $ # # This file contains common `MI' targets and definitions and it is included # at the bottom of each `MD' ${MACHINE}/conf/Makefile.${MACHINE}. @@ -120,16 +120,27 @@ # COPTS.debugsyms.c+= -g +# Add CTF sections for DTrace +.if defined(CTFCONVERT) +COMPILE_CTFCONVERT= ${_MKSHECHO}\ + ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}; \ + ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} +.else +COMPILE_CTFCONVERT= ${_MKSHECHO} +.endif + # compile rules: rules are named ${TYPE}_${SUFFIX} where TYPE is NORMAL or # NOPROF and SUFFIX is the file suffix, capitalized (e.g. C for a .c file). NORMAL_C?= @${_MKSHMSG} "compile ${.CURDIR:T}/${.TARGET}"; \ ${_MKSHECHO}\ ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<; \ - ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $< + ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<; \ + ${COMPILE_CTFCONVERT} NOPROF_C?= @${_MKSHMSG} "compile ${.CURDIR:T}/${.TARGET}"; \ ${_MKSHECHO}\ ${CC} ${CFLAGS} ${CPPFLAGS} -c $<; \ - ${CC} ${CFLAGS} ${CPPFLAGS} -c $< + ${CC} ${CFLAGS} ${CPPFLAGS} -c $<; \ + ${COMPILE_CTFCONVERT} NORMAL_S?= @${_MKSHMSG} "compile ${.CURDIR:T}/${.TARGET}"; \ ${_MKSHECHO}\ ${CC} ${AFLAGS} ${CPPFLAGS} -c $<; \ @@ -199,13 +210,19 @@ # ${SYSTEM_LD_TAIL} SYSTEM_OBJ?= ${MD_OBJS} ${MI_OBJS} ${OBJS:O} ${SYSLIBCOMPAT} ${LIBKERN} SYSTEM_DEP?= Makefile ${SYSTEM_OBJ:O} .gdbinit +.if defined(CTFMERGE) +SYSTEM_CTFMERGE= ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o +.else +SYSTEM_CTFMERGE= ${_MKSHECHO} +.endif system_ld_hea...@rm -f $@ SYSTEM_LD?= @${_MKSHMSG} " link ${.CURDIR:T}/${.TARGET}"; \ ${_MKSHECHO}\ ${LD} -Map $...@.map --cref ${LINKFLAGS} -o $@ '$${SYSTEM_OBJ}' '$${EXTRA_OBJ}' vers.o; \ ${LD} -Map $...@.map --cref ${LINKFLAGS} -o $@ ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o system_ld_tai...@${tool_sed} '/const char sccs/!d;s/.*@(.)//;s/\\.*//' vers.c; \ - ${SIZE} $@; chmod 755 $@ + ${SIZE} $@; chmod 755 $@; \ + ${SYSTEM_CTFMERGE} TEXTADDR?= ${LOADADDRESS} # backwards compatibility LINKTEXT?= ${TEXTADDR:C/.+/-Ttext &/} @@ -228,6 +245,7 @@ SYSTEM_LD_TAIL+=${SYSTEM_LD_TAIL_DEBUG} LINKFLAGS+= ${LINKFLAGS_DEBUG} EXTRA_KERNELS+= ${KERNELS:@.kern...@${.kernel.}.gdb@} +CTFFLAGS+= -g .elifndef PROF LINKFLAGS+= ${LINKFLAGS_NORMAL} .endif Index: src/sys/conf/files diff -u src/sys/conf/files:1.977 src/sys/conf/files:1.978 --- src/sys/conf/files:1.977 Tue Feb 23 22:21:25 2010 +++ src/sys/conf/files Mon Mar 1 21:10:14 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.977 2010/02/23 22:21:25 darran Exp $ +# $NetBSD: files,v 1.978 2010/03/01 21:10:14 darran Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20090313 @@ -1456,6 +1456,7 @@ file kern/kern_runq.c file kern/kern_rwlock.c file kern/kern_rwlock_obj.c +file kern/kern_sdt.c kdtrace_hooks file kern/kern_sig.c file kern/kern_sleepq.c file kern/kern_softint.c Index: src/sys/kern/kern_exec.c diff -u src/sys/kern/kern_exec.c:1.293 src/sys/kern/kern_exec.c:1.294 --- src/sys/kern/kern_exec.c:1.293 Fri Jan 8 11:35:10 2010 +++ src/sys/kern/kern_exec.c Mon Mar 1 21:10:15 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.293 2010/01/08 11:35:10 pooka Exp $ */ +/* $NetBSD: kern_exec.c,v 1.294 2010/03/01 21:10:15 darran Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.293 2010/01/08 11:35:10 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.294 2010/03/01 21:10:15 darran Exp $"); #include "opt_ktrace.h" #include "opt_modular.h" @@ -101,6 +101,7 @@ #if NVERIEXEC > 0 #include <sys/verified_exec.h> #endif /* NVERIEXEC > 0 */ +#include <sys/sdt.h> #include <uvm/uvm_extern.h> @@ -117,6 +118,22 @@ #endif /* DEBUG_EXEC */ /* + * DTrace SDT provider definitions + */ +SDT_PROBE_DEFINE(proc,,,exec, + "char *", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); +SDT_PROBE_DEFINE(proc,,,exec_success, + "char *", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); +SDT_PROBE_DEFINE(proc,,,exec_failure, + "int", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + +/* * Exec function switch: * * Note that each makecmds function is responsible for loading the @@ -520,6 +537,8 @@ p = l->l_proc; modgen = 0; + SDT_PROBE(proc,,,exec, path, 0, 0, 0, 0); + /* * Check if we have exceeded our number of processes limit. * This is so that we handle the case where a root daemon @@ -1063,6 +1082,8 @@ kmem_free(pack.ep_hdr, pack.ep_hdrlen); + SDT_PROBE(proc,,,exec_success, path, 0, 0, 0, 0); + /* The emulation root will usually have been found when we looked * for the elf interpreter (or similar), if not look now. */ if (pack.ep_esch->es_emul->e_path != NULL && pack.ep_emul_root == NULL) @@ -1181,9 +1202,11 @@ goto retry; } + SDT_PROBE(proc,,,exec_failure, error, 0, 0, 0, 0); return error; exec_abort: + SDT_PROBE(proc,,,exec_failure, error, 0, 0, 0, 0); PNBUF_PUT(pathbuf); rw_exit(&p->p_reflock); rw_exit(&exec_lock); Index: src/sys/kern/kern_exit.c diff -u src/sys/kern/kern_exit.c:1.225 src/sys/kern/kern_exit.c:1.226 --- src/sys/kern/kern_exit.c:1.225 Wed Nov 4 21:23:02 2009 +++ src/sys/kern/kern_exit.c Mon Mar 1 21:10:15 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exit.c,v 1.225 2009/11/04 21:23:02 rmind Exp $ */ +/* $NetBSD: kern_exit.c,v 1.226 2010/03/01 21:10:15 darran Exp $ */ /*- * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.225 2009/11/04 21:23:02 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.226 2010/03/01 21:10:15 darran Exp $"); #include "opt_ktrace.h" #include "opt_perfctrs.h" @@ -109,6 +109,7 @@ #include <sys/cpu.h> #include <sys/lwpctl.h> #include <sys/atomic.h> +#include <sys/sdt.h> #include <uvm/uvm_extern.h> @@ -123,6 +124,13 @@ static void proc_free(struct proc *, struct rusage *); /* + * DTrace SDT provider definitions + */ +SDT_PROBE_DEFINE(proc,,,exit, + "int", NULL, /* reason */ + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); +/* * Fill in the appropriate signal information, and signal the parent. */ static void @@ -402,6 +410,11 @@ */ KNOTE(&p->p_klist, NOTE_EXIT); + SDT_PROBE(proc,,,exit, + (WCOREDUMP(rv) ? CLD_DUMPED : + (WIFSIGNALED(rv) ? CLD_KILLED : CLD_EXITED)), + 0,0,0,0); + #if PERFCTRS /* * Save final PMC information in parent process & clean up. Index: src/sys/kern/kern_fork.c diff -u src/sys/kern/kern_fork.c:1.175 src/sys/kern/kern_fork.c:1.176 --- src/sys/kern/kern_fork.c:1.175 Fri Jan 8 11:35:10 2010 +++ src/sys/kern/kern_fork.c Mon Mar 1 21:10:16 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_fork.c,v 1.175 2010/01/08 11:35:10 pooka Exp $ */ +/* $NetBSD: kern_fork.c,v 1.176 2010/03/01 21:10:16 darran Exp $ */ /*- * Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.175 2010/01/08 11:35:10 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.176 2010/03/01 21:10:16 darran Exp $"); #include "opt_ktrace.h" @@ -91,9 +91,19 @@ #include <sys/atomic.h> #include <sys/syscallargs.h> #include <sys/uidinfo.h> +#include <sys/sdt.h> #include <uvm/uvm_extern.h> +/* + * DTrace SDT provider definitions + */ +SDT_PROBE_DEFINE(proc,,,create, + "struct proc *", NULL, /* new process */ + "struct proc *", NULL, /* parent process */ + "int", NULL, /* flags */ + NULL, NULL, NULL, NULL); + u_int nprocs = 1; /* process 0 */ /* @@ -416,6 +426,8 @@ uvm_proc_fork(p1, p2, (flags & FORK_SHAREVM) ? true : false); + SDT_PROBE(proc,,,create, p2, p1, flags, 0, 0); + /* * Finish creating the child process. * It will return through a different path later. Index: src/sys/kern/kern_ksyms.c diff -u src/sys/kern/kern_ksyms.c:1.53 src/sys/kern/kern_ksyms.c:1.54 --- src/sys/kern/kern_ksyms.c:1.53 Sun Jan 31 00:43:37 2010 +++ src/sys/kern/kern_ksyms.c Mon Mar 1 21:10:16 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_ksyms.c,v 1.53 2010/01/31 00:43:37 hubertf Exp $ */ +/* $NetBSD: kern_ksyms.c,v 1.54 2010/03/01 21:10:16 darran Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.53 2010/01/31 00:43:37 hubertf Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.54 2010/03/01 21:10:16 darran Exp $"); #if defined(_KERNEL) && defined(_KERNEL_OPT) #include "opt_ddb.h" @@ -124,6 +124,7 @@ int ksyms_symsz; int ksyms_strsz; +int ksyms_ctfsz = 0; TAILQ_HEAD(, ksyms_symtab) ksyms_symtabs = TAILQ_HEAD_INITIALIZER(ksyms_symtabs); static struct ksyms_symtab kernel_symtab; @@ -264,7 +265,7 @@ static void addsymtab(const char *name, void *symstart, size_t symsize, void *strstart, size_t strsize, struct ksyms_symtab *tab, - void *newstart) + void *newstart, void *ctfstart, size_t ctfsize) { Elf_Sym *sym, *nsym, ts; int i, j, n, nglob; @@ -279,6 +280,8 @@ tab->sd_maxsym = 0; tab->sd_usroffset = 0; tab->sd_gone = false; + tab->sd_ctfstart = ctfstart; + tab->sd_ctfsize = ctfsize; #ifdef KSYMS_DEBUG printf("newstart %p sym %p ksyms_symsz %d str %p strsz %d send %p\n", newstart, symstart, symsize, strstart, strsize, @@ -353,6 +356,8 @@ char *symstart = NULL, *strstart = NULL; size_t strsize = 0; Elf_Ehdr *ehdr; + char *ctfstart = NULL; + size_t ctfsize = 0; if (symsize <= 0) { printf("[ Kernel symbol table missing! ]\n"); @@ -397,10 +402,26 @@ break; } + /* Find the CTF section */ + shdr = (Elf_Shdr *)((uint8_t *)start + ehdr->e_shoff); + for (i = 1; i < ehdr->e_shnum; i++) { + if (shdr[i].sh_type != SHT_PROGBITS) + continue; + if (strncmp(".SUNW_ctf", &strstart[shdr[i].sh_name] ,10) != 0) + continue; + ctfstart = (uint8_t *)start + shdr[i].sh_offset; + ctfsize = shdr[i].sh_size; + ksyms_ctfsz = ctfsize; + printf("%s: found CTF at 0x%x, size 0x%x\n", + __func__, + (uint32_t)ctfstart, ctfsize); + break; + } + if (!ksyms_verify(symstart, strstart)) return; addsymtab("netbsd", symstart, symsize, strstart, strsize, - &kernel_symtab, start); + &kernel_symtab, start, ctfstart, ctfsize); #ifdef DEBUG aprint_normal("Loaded initial symtab at %p, strtab at %p, # entries %ld\n", @@ -427,7 +448,7 @@ ksyms_hdr_init(ehdr); addsymtab("netbsd", symstart, symsize, strstart, strsize, - &kernel_symtab, symstart); + &kernel_symtab, symstart, NULL, 0); } /* @@ -548,7 +569,8 @@ st = kmem_zalloc(sizeof(*st), KM_SLEEP); mutex_enter(&ksyms_lock); - addsymtab(name, symstart, symsize, strstart, strsize, st, symstart); + addsymtab(name, symstart, symsize, strstart, strsize, st, symstart, + NULL, 0); mutex_exit(&ksyms_lock); } @@ -716,12 +738,20 @@ /* Fifth section, ".bss". All symbols reside here. */ ksyms_hdr.kh_shdr[SHBSS].sh_name = 27; /* This section name offset */ - ksyms_hdr.kh_shdr[SHBSS].sh_type = SHT_NOBITS; + ksyms_hdr.kh_shdr[SHBSS].sh_type = SHT_SYMTAB; ksyms_hdr.kh_shdr[SHBSS].sh_offset = 0; ksyms_hdr.kh_shdr[SHBSS].sh_size = (unsigned long)-1L; ksyms_hdr.kh_shdr[SHBSS].sh_addralign = PAGE_SIZE; ksyms_hdr.kh_shdr[SHBSS].sh_flags = SHF_ALLOC | SHF_EXECINSTR; + /* Sixth section, ".SUNW_ctf". CTF section for DTrace */ + ksyms_hdr.kh_shdr[SHCTF].sh_name = 32; /* This section name offset */ + ksyms_hdr.kh_shdr[SHCTF].sh_type = SHT_NOBITS; +/* ksyms_hdr.kh_shdr[SHCTF].sh_offset = filled at open; */ +/* ksyms_hdr.kh_shdr[SHCTF].sh_size = filled at open; */ + ksyms_hdr.kh_shdr[SHCTF].sh_addralign = PAGE_SIZE; + ksyms_hdr.kh_shdr[SHCTF].sh_flags = 0; + /* Set section names */ strlcpy(&ksyms_hdr.kh_strtab[1], ".symtab", sizeof(ksyms_hdr.kh_strtab) - 1); @@ -731,6 +761,8 @@ sizeof(ksyms_hdr.kh_strtab) - 17); strlcpy(&ksyms_hdr.kh_strtab[27], ".bss", sizeof(ksyms_hdr.kh_strtab) - 27); + strlcpy(&ksyms_hdr.kh_strtab[32], ".SUNW_ctf", + sizeof(ksyms_hdr.kh_strtab) - 32); } static int @@ -747,8 +779,11 @@ mutex_enter(&ksyms_lock); ksyms_hdr.kh_shdr[SYMTAB].sh_size = ksyms_symsz; ksyms_hdr.kh_shdr[SYMTAB].sh_info = ksyms_symsz / sizeof(Elf_Sym); - ksyms_hdr.kh_shdr[STRTAB].sh_offset = ksyms_symsz + + ksyms_hdr.kh_shdr[SHCTF].sh_size = ksyms_ctfsz; + ksyms_hdr.kh_shdr[SHCTF].sh_offset = ksyms_symsz + ksyms_hdr.kh_shdr[SYMTAB].sh_offset; + ksyms_hdr.kh_shdr[STRTAB].sh_offset = + ksyms_hdr.kh_shdr[SHCTF].sh_offset + ksyms_ctfsz; ksyms_hdr.kh_shdr[STRTAB].sh_size = ksyms_strsz; ksyms_isopen = true; mutex_exit(&ksyms_lock); @@ -784,7 +819,7 @@ static int ksymsread(dev_t dev, struct uio *uio, int ioflag) { - struct ksyms_symtab *st; + struct ksyms_symtab *st, *cst; size_t filepos, inpos, off; int error; @@ -818,10 +853,29 @@ } /* + * Copy out the CTF table. + */ + cst = TAILQ_FIRST(&ksyms_symtabs); + printf("%s: ctf start 0x%x size 0x%x\n", + __func__, + (uint32_t)cst->sd_ctfstart, cst->sd_ctfsize); + if (uio->uio_resid == 0) + return 0; + if (uio->uio_offset <= cst->sd_symsize + filepos) { + inpos = uio->uio_offset - filepos; + error = uiomove((char *)cst->sd_ctfstart + inpos, + cst->sd_ctfsize - inpos, uio); + if (error != 0) + return error; + } + filepos += cst->sd_ctfsize; + + /* * Copy out the string table */ KASSERT(filepos == sizeof(struct ksyms_hdr) + - ksyms_hdr.kh_shdr[SYMTAB].sh_size); + ksyms_hdr.kh_shdr[SYMTAB].sh_size + + ksyms_hdr.kh_shdr[SHCTF].sh_size); TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { if (uio->uio_resid == 0) return 0; Index: src/sys/kern/kern_lwp.c diff -u src/sys/kern/kern_lwp.c:1.140 src/sys/kern/kern_lwp.c:1.141 --- src/sys/kern/kern_lwp.c:1.140 Tue Feb 23 22:19:27 2010 +++ src/sys/kern/kern_lwp.c Mon Mar 1 21:10:17 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lwp.c,v 1.140 2010/02/23 22:19:27 darran Exp $ */ +/* $NetBSD: kern_lwp.c,v 1.141 2010/03/01 21:10:17 darran Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -209,7 +209,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.140 2010/02/23 22:19:27 darran Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.141 2010/03/01 21:10:17 darran Exp $"); #include "opt_ddb.h" #include "opt_lockdebug.h" @@ -237,6 +237,7 @@ #include <sys/atomic.h> #include <sys/filedesc.h> #include <sys/dtrace_bsd.h> +#include <sys/sdt.h> #include <uvm/uvm_extern.h> #include <uvm/uvm_object.h> @@ -248,6 +249,20 @@ static pool_cache_t lwp_cache; static specificdata_domain_t lwp_specificdata_domain; +/* DTrace proc provider probes */ +SDT_PROBE_DEFINE(proc,,,lwp_create, + "struct lwp *", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); +SDT_PROBE_DEFINE(proc,,,lwp_start, + "struct lwp *", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); +SDT_PROBE_DEFINE(proc,,,lwp_exit, + "struct lwp *", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + void lwpinit(void) { @@ -681,6 +696,8 @@ } mutex_exit(p2->p_lock); + SDT_PROBE(proc,,,lwp_create, l2, 0,0,0,0); + mutex_enter(proc_lock); LIST_INSERT_HEAD(&alllwp, l2, l_list); mutex_exit(proc_lock); @@ -702,6 +719,8 @@ lwp_startup(struct lwp *prev, struct lwp *new) { + SDT_PROBE(proc,,,lwp_start, new, 0,0,0,0); + KASSERT(kpreempt_disabled()); if (prev != NULL) { /* @@ -738,6 +757,8 @@ KASSERT(current || (l->l_stat == LSIDL && l->l_target_cpu == NULL)); KASSERT(p == curproc); + SDT_PROBE(proc,,,lwp_exit, l, 0,0,0,0); + /* * Verify that we hold no locks other than the kernel lock. */ Index: src/sys/kern/kern_sig.c diff -u src/sys/kern/kern_sig.c:1.302 src/sys/kern/kern_sig.c:1.303 --- src/sys/kern/kern_sig.c:1.302 Wed Dec 30 23:31:56 2009 +++ src/sys/kern/kern_sig.c Mon Mar 1 21:10:17 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sig.c,v 1.302 2009/12/30 23:31:56 rmind Exp $ */ +/* $NetBSD: kern_sig.c,v 1.303 2010/03/01 21:10:17 darran Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.302 2009/12/30 23:31:56 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.303 2010/03/01 21:10:17 darran Exp $"); #include "opt_ptrace.h" #include "opt_compat_sunos.h" @@ -96,6 +96,7 @@ #include <sys/atomic.h> #include <sys/cpu.h> #include <sys/module.h> +#include <sys/sdt.h> #ifdef PAX_SEGVGUARD #include <sys/pax.h> @@ -124,6 +125,30 @@ int (*coredump_vec)(struct lwp *, const char *) = (int (*)(struct lwp *, const char *))enosys; +/* + * DTrace SDT provider definitions + */ +SDT_PROBE_DEFINE(proc,,,signal_send, + "struct lwp *", NULL, /* target thread */ + "struct proc *", NULL, /* target process */ + "int", NULL, /* signal */ + NULL, NULL, NULL, NULL); +SDT_PROBE_DEFINE(proc,,,signal_discard, + "struct lwp *", NULL, /* target thread */ + "struct proc *", NULL, /* target process */ + "int", NULL, /* signal */ + NULL, NULL, NULL, NULL); +SDT_PROBE_DEFINE(proc,,,signal_clear, + "int", NULL, /* signal */ + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); +SDT_PROBE_DEFINE(proc,,,signal_handle, + "int", NULL, /* signal */ + "ksiginfo_t *", NULL, + "void (*)(void)", NULL, /* handler address */ + NULL, NULL, NULL, NULL); + + static struct pool_allocator sigactspool_allocator = { .pa_alloc = sigacts_poolpage_alloc, .pa_free = sigacts_poolpage_free @@ -1071,6 +1096,8 @@ if (l->l_refcnt == 0) return 0; + SDT_PROBE(proc,,,signal_send, l, p, sig, 0, 0); + /* * Have the LWP check for signals. This ensures that even if no LWP * is found to take the signal immediately, it should be taken soon. @@ -1835,6 +1862,10 @@ prop = sigprop[signo]; + /* XXX no siginfo? */ + SDT_PROBE(proc,,,signal_handle, signo, 0, + SIGACTION(p, signo).sa_handler, 0, 0); + /* * Decide whether the signal should be returned. */ Index: src/sys/modules/dtrace/Makefile diff -u src/sys/modules/dtrace/Makefile:1.1 src/sys/modules/dtrace/Makefile:1.2 --- src/sys/modules/dtrace/Makefile:1.1 Sun Feb 21 11:16:19 2010 +++ src/sys/modules/dtrace/Makefile Mon Mar 1 21:10:18 2010 @@ -1,8 +1,8 @@ -# $NetBSD: Makefile,v 1.1 2010/02/21 11:16:19 darran Exp $ +# $NetBSD: Makefile,v 1.2 2010/03/01 21:10:18 darran Exp $ # $FreeBSD: src/sys/modules/dtrace/Makefile,v 1.6.2.1 2009/08/03 08:13:06 kensmith Exp $ .include <bsd.own.mk> -SUBDIR= dtrace +SUBDIR= dtrace sdt .include <bsd.subdir.mk> Index: src/sys/sys/Makefile diff -u src/sys/sys/Makefile:1.125 src/sys/sys/Makefile:1.126 --- src/sys/sys/Makefile:1.125 Mon Mar 1 11:25:05 2010 +++ src/sys/sys/Makefile Mon Mar 1 21:10:13 2010 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.125 2010/03/01 11:25:05 darran Exp $ +# $NetBSD: Makefile,v 1.126 2010/03/01 21:10:13 darran Exp $ .include <bsd.sys.mk> @@ -29,7 +29,7 @@ queue.h \ ras.h rb.h reboot.h radioio.h resource.h resourcevar.h rmd160.h \ rnd.h rwlock.h sa.h satypes.h \ - scanio.h sched.h scsiio.h select.h selinfo.h sem.h sha1.h \ + scanio.h sched.h scsiio.h sdt.h select.h selinfo.h sem.h sha1.h \ sha2.h shm.h siginfo.h signal.h signalvar.h sigtypes.h simplelock.h \ sleepq.h socket.h \ socketvar.h sockio.h specificdata.h stat.h statvfs.h \ Index: src/sys/sys/ksyms.h diff -u src/sys/sys/ksyms.h:1.23 src/sys/sys/ksyms.h:1.24 --- src/sys/sys/ksyms.h:1.23 Sat Mar 7 21:59:25 2009 +++ src/sys/sys/ksyms.h Mon Mar 1 21:10:13 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ksyms.h,v 1.23 2009/03/07 21:59:25 ad Exp $ */ +/* $NetBSD: ksyms.h,v 1.24 2010/03/01 21:10:13 darran Exp $ */ /* * Copyright (c) 2001, 2003 Anders Magnusson (ra...@ludd.luth.se). @@ -47,6 +47,8 @@ int sd_strsize; /* Size of string table */ int sd_nglob; /* Number of global symbols */ bool sd_gone; /* dead but around for open() */ + void *sd_ctfstart; /* Address of CTF contents */ + int sd_ctfsize; /* Size in bytes of CTF contents */ }; /* @@ -57,10 +59,11 @@ #define STRTAB 2 #define SHSTRTAB 3 #define SHBSS 4 -#define NSECHDR 5 +#define SHCTF 5 +#define NSECHDR 6 #define NPRGHDR 1 -#define SHSTRSIZ 32 +#define SHSTRSIZ 42 struct ksyms_hdr { Elf_Ehdr kh_ehdr; Added files: Index: src/sys/kern/kern_sdt.c diff -u /dev/null src/sys/kern/kern_sdt.c:1.1 --- /dev/null Mon Mar 1 21:10:20 2010 +++ src/sys/kern/kern_sdt.c Mon Mar 1 21:10:17 2010 @@ -0,0 +1,110 @@ +/* $NetBSD: kern_sdt.c,v 1.1 2010/03/01 21:10:17 darran Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by CoyotePoint Systems, Inc. It was developed under contract to + * CoyotePoint by Darran Hunt. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright 2006-2008 John Birrell <j...@freebsd.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/kern/kern_sdt.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $ + * + * Backend for the Statically Defined Tracing (SDT) kernel support. This is + * required to allow a module to load even though DTrace kernel support may + * not be present. A module may be built with SDT probes in it. + * + */ + +#include <sys/cdefs.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/sdt.h> + +void sdt_probe_stub(u_int32_t, uintptr_t, uintptr_t, + uintptr_t, uintptr_t, uintptr_t); + +/* + * Hook for the DTrace probe function. The 'sdt' provider will set this + * to dtrace_probe when it loads. + */ +sdt_probe_func_t sdt_probe_func = sdt_probe_stub; + +/* + * This is a stub for probe calls in case kernel DTrace support isn't + * compiled in. It should never get called because there is no DTrace + * support to enable it. + */ +void +sdt_probe_stub(u_int32_t id, uintptr_t arg0, uintptr_t arg1, + uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) +{ + printf("%s: XXX should not be called\n", __func__); +} + +/* + * initialize the SDT dtrace probe function + */ +void +sdt_init(void *dtrace_probe) +{ + + sdt_probe_func = dtrace_probe; +} + +/* + * Disable the SDT dtrace probe function + */ +void +sdt_exit(void) +{ + + sdt_probe_func = sdt_probe_stub; +} Index: src/sys/modules/dtrace/sdt/Makefile diff -u /dev/null src/sys/modules/dtrace/sdt/Makefile:1.1 --- /dev/null Mon Mar 1 21:10:20 2010 +++ src/sys/modules/dtrace/sdt/Makefile Mon Mar 1 21:10:19 2010 @@ -0,0 +1,13 @@ +# $FreeBSD: src/sys/modules/dtrace/sdt/Makefile,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $ + +.PATH: ${NETBSDSRCDIR}/external/cddl/osnet/dev/sdt + +KMOD= sdt +SRCS= sdt.c +SRCS+= vnode_if.h + +CPPFLAGS+= -I${NETBSDSRCDIR}/external/cddl/osnet/sys \ + -I${NETBSDSRCDIR}/external/cddl/osnet/dev/sdt \ + -I${NETBSDSRCDIR}/external/cddl/osnet/dist/uts/common + +.include <bsd.kmodule.mk> Index: src/sys/sys/sdt.h diff -u /dev/null src/sys/sys/sdt.h:1.1 --- /dev/null Mon Mar 1 21:10:20 2010 +++ src/sys/sys/sdt.h Mon Mar 1 21:10:13 2010 @@ -0,0 +1,128 @@ +/* $NetBSD: sdt.h,v 1.1 2010/03/01 21:10:13 darran Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by CoyotePoint Systems, Inc. It was developed under contract to + * CoyotePoint by Darran Hunt. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SDT_H_ +#define _SDT_H_ + +#if defined(_KERNEL_OPT) +#include "opt_dtrace.h" +#endif + +#define SDT_MAX_PROVIDER 1024 /* max number of SDT providers */ +#define SDT_MAX_ARGS 5 /* max number of probe arguments */ +#define SDT_MAX_NAME_SIZE 64 /* max size of provider name */ + +typedef struct { + int created; /* boolean: probe created? */ + int enabled; /* boolean: probe enabled? */ + int id; /* dtrace provided probe id */ + const char *provider; /* provider name */ + const char *module; /* module name */ + const char *function; /* function name */ + const char *name; /* probe name */ + const char *argv[SDT_MAX_ARGS]; /* probe argument types */ + const char *argx[SDT_MAX_ARGS]; /* probe argument xlate types */ +} sdt_probe_t; + + +/* + * This type definition must match that of dtrace_probe. It is defined this + * way to avoid having to rely on CDDL code. + */ +typedef void (*sdt_probe_func_t)(u_int32_t, uintptr_t arg0, uintptr_t arg1, + uintptr_t arg2, uintptr_t arg3, uintptr_t arg4); + +/* + * The hook for the probe function. See kern_sdt.c which defaults this to + * it's own stub. The 'sdt' provider will set it to dtrace_probe when it + * loads. + */ +extern sdt_probe_func_t sdt_probe_func; + + +#define SDT_NAME(prov, mod, func, name) \ + prov##_##mod##_##func##_##name + +#ifdef KDTRACE_HOOKS +/* + * SDT_PROBE_DEFINE(prov, mod, func, name, + * arg0, argx0, arg1, argx1, + * arg2, argx2, arg3, argx3, arg4, argx4) + * + * prov - provider name + * mod - module name + * func - function name + * name - probe name + * arg0 - arg4, argument types as strings, or NULL. + * argx0 - argx4, translation types for arg0 - arg4 + * + * e.g. SDT_PROBE_DEFINE(l7, l7lb, l7lb_create_node, + * "void *", NULL, + * NULL, NULL, NULL, NULL, + * NULL, NULL, NULL NULL, ) + * + * This is used in the target module to define probes to be used. + * The translation type should be set to NULL if not used. + */ +#define SDT_PROBE_DEFINE(prov, mod, func, name, \ + arg0, argx0, arg1, argx1, arg2, argx2, \ + arg3, argx3, arg4, argx4) \ + sdt_probe_t SDT_NAME(prov, mod, func, name) = { \ + 0, 0, 0, #prov, #mod, #func, #name, \ + { arg0, arg1, arg2, arg3, arg4 }, \ + { NULL, NULL, NULL, NULL, NULL } \ + } + +/* Use this in this module to declare probes defined in the kernel. */ +#define SDT_PROBE_DECLARE(prov, mod, func, name) \ + extern sdt_probe_t SDT_NAME(prov, mod, func, name); + +/* Use this in the target modules to provide instrumentation points */ +#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) \ + if (__predict_false(SDT_NAME(prov, mod, func, name).enabled)) { \ + (*sdt_probe_func)(SDT_NAME(prov, mod, func, name).id, \ + (uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), \ + (uintptr_t)(arg3), (uintptr_t)(arg4)); \ + } +#else +#define SDT_PROBE_DEFINE(prov, mod, func, name, \ + arg0, argx0, arg1, argx1, arg2, argx2, \ + arg3, argx3, arg4, argx4) +#define SDT_PROBE_DECLARE(prov, mod, func, name) +#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) +#endif + +void sdt_init(void *); +void sdt_exit(void); + +#endif