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 [email protected]
- *
- * $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 [email protected] --cref ${LINKFLAGS} -o $@ '$${SYSTEM_OBJ}' '$${EXTRA_OBJ}' vers.o; \
${LD} -Map [email protected] --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 ([email protected]).
@@ -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 <[email protected]>
+ *
+ * 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