diff options
author | gnn <gnn@FreeBSD.org> | 2012-07-11 16:27:02 +0000 |
---|---|---|
committer | gnn <gnn@FreeBSD.org> | 2012-07-11 16:27:02 +0000 |
commit | 786ac825530572ff02b9440ed00f28096197f9b9 (patch) | |
tree | eabb05d032e7a979640db2928991f11bb1d8758f | |
parent | ec38b41c3eecfc3b4fb8ebfac57ad414dd1aa654 (diff) | |
download | FreeBSD-src-786ac825530572ff02b9440ed00f28096197f9b9.zip FreeBSD-src-786ac825530572ff02b9440ed00f28096197f9b9.tar.gz |
Initial commit of an I/O provider for DTrace on FreeBSD.
These probes are most useful when looking into the structures
they provide, which are listed in io.d. For example:
dtrace -n 'io:genunix::start { printf("%d\n", args[0]->bio_bcount); }'
Note that the I/O systems in FreeBSD and Solaris/Illumos are sufficiently
different that there is not a 1:1 mapping from scripts that work
with one to the other.
MFC after: 1 month
-rw-r--r-- | cddl/lib/libdtrace/Makefile | 1 | ||||
-rw-r--r-- | cddl/lib/libdtrace/io.d | 178 | ||||
-rw-r--r-- | sys/kern/dtio_kdtrace.c | 232 | ||||
-rw-r--r-- | sys/kern/subr_devstat.c | 54 | ||||
-rw-r--r-- | sys/modules/dtrace/Makefile | 1 | ||||
-rw-r--r-- | sys/modules/dtrace/dtio/Makefile | 13 | ||||
-rw-r--r-- | sys/modules/dtrace/dtraceall/dtraceall.c | 1 | ||||
-rw-r--r-- | sys/sys/dtrace_bsd.h | 19 |
8 files changed, 355 insertions, 144 deletions
diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile index 81396ff..bdd8acc 100644 --- a/cddl/lib/libdtrace/Makefile +++ b/cddl/lib/libdtrace/Makefile @@ -45,6 +45,7 @@ SRCS= dt_aggregate.c \ gmatch.c DSRCS= errno.d \ + io.d \ psinfo.d \ signal.d \ unistd.d diff --git a/cddl/lib/libdtrace/io.d b/cddl/lib/libdtrace/io.d index 0bd5a06..18a54af 100644 --- a/cddl/lib/libdtrace/io.d +++ b/cddl/lib/libdtrace/io.d @@ -27,114 +27,50 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#pragma D depends_on module unix #pragma D depends_on provider io -inline int B_BUSY = B_BUSY; -#pragma D binding "1.0" B_BUSY -inline int B_DONE = 0x00000200; -#pragma D binding "1.0" B_DONE -inline int B_ERROR = B_ERROR; -#pragma D binding "1.0" B_ERROR -inline int B_PAGEIO = B_PAGEIO; -#pragma D binding "1.0" B_PAGEIO -inline int B_PHYS = B_PHYS; -#pragma D binding "1.0" B_PHYS -inline int B_READ = B_READ; -#pragma D binding "1.0" B_READ -inline int B_WRITE = B_WRITE; -#pragma D binding "1.0" B_WRITE -inline int B_ASYNC = 0x00000004; -#pragma D binding "1.0" B_ASYNC - -typedef struct bufinfo { - int b_flags; /* buffer status */ - size_t b_bcount; /* number of bytes */ - caddr_t b_addr; /* buffer address */ - uint64_t b_lblkno; /* block # on device */ - uint64_t b_blkno; /* expanded block # on device */ - size_t b_resid; /* # of bytes not transferred */ - size_t b_bufsize; /* size of allocated buffer */ - caddr_t b_iodone; /* I/O completion routine */ - int b_error; /* expanded error field */ - dev_t b_edev; /* extended device */ -} bufinfo_t; - -#pragma D binding "1.0" translator -translator bufinfo_t < struct buf *B > { - b_flags = B->b_flags; - b_addr = B->b_un.b_addr; - b_bcount = B->b_bcount; - b_lblkno = B->_b_blkno._f; - b_blkno = sizeof (long) == 8 ? B->_b_blkno._f : B->_b_blkno._p._l; - b_resid = B->b_resid; - b_bufsize = B->b_bufsize; - b_iodone = (caddr_t)B->b_iodone; - b_error = B->b_error; - b_edev = B->b_edev; -}; - typedef struct devinfo { - int dev_major; /* major number */ - int dev_minor; /* minor number */ - int dev_instance; /* instance number */ - string dev_name; /* name of device */ - string dev_statname; /* name of device + instance/minor */ - string dev_pathname; /* pathname of device */ + int dev_major; /* major number */ + int dev_minor; /* minor number */ + int dev_instance; /* instance number */ + string dev_name; /* name of device */ + string dev_statname; /* name of device + instance/minor */ + string dev_pathname; /* pathname of device */ } devinfo_t; #pragma D binding "1.0" translator -translator devinfo_t < struct buf *B > { - dev_major = B->b_dip != NULL ? getmajor(B->b_edev) : - getmajor(B->b_file->v_vfsp->vfs_dev); - dev_minor = B->b_dip != NULL ? getminor(B->b_edev) : - getminor(B->b_file->v_vfsp->vfs_dev); - dev_instance = B->b_dip == NULL ? - getminor(B->b_file->v_vfsp->vfs_dev) : - ((struct dev_info *)B->b_dip)->devi_instance; - dev_name = B->b_dip == NULL ? "nfs" : - stringof(`devnamesp[getmajor(B->b_edev)].dn_name); - dev_statname = strjoin(B->b_dip == NULL ? "nfs" : - stringof(`devnamesp[getmajor(B->b_edev)].dn_name), - lltostr(B->b_dip == NULL ? getminor(B->b_file->v_vfsp->vfs_dev) : - ((struct dev_info *)B->b_dip)->devi_instance == 0 && - ((struct dev_info *)B->b_dip)->devi_parent != NULL && - ((struct dev_info *)B->b_dip)->devi_parent->devi_node_name == - "pseudo" ? getminor(B->b_edev) : - ((struct dev_info *)B->b_dip)->devi_instance)); - dev_pathname = B->b_dip == NULL ? "<nfs>" : - ddi_pathname(B->b_dip, getminor(B->b_edev)); +translator devinfo_t < struct devstat *D > { + dev_major = D->device_number; + dev_minor = D->unit_number; + dev_instance = 0; + dev_name = stringof(D->device_name); + dev_statname = stringof(D->device_name); + dev_pathname = stringof(D->device_name); }; -typedef struct fileinfo { - string fi_name; /* name (basename of fi_pathname) */ - string fi_dirname; /* directory (dirname of fi_pathname) */ - string fi_pathname; /* full pathname */ - offset_t fi_offset; /* offset within file */ - string fi_fs; /* filesystem */ - string fi_mount; /* mount point of file system */ - int fi_oflags; /* open(2) flags for file descriptor */ -} fileinfo_t; +typedef struct bufinfo { + int b_flags; /* flags */ + long b_bcount; /* number of bytes */ + caddr_t b_addr; /* buffer address */ + uint64_t b_blkno; /* expanded block # on device */ + uint64_t b_lblkno; /* block # on device */ + size_t b_resid; /* # of bytes not transferred */ + size_t b_bufsize; /* size of allocated buffer */ +/* caddr_t b_iodone; I/O completion routine */ + int b_error; /* expanded error field */ +/* dev_t b_edev; extended device */ +} bufinfo_t; #pragma D binding "1.0" translator -translator fileinfo_t < struct buf *B > { - fi_name = B->b_file == NULL ? "<none>" : - B->b_file->v_path == NULL ? "<unknown>" : - basename(cleanpath(B->b_file->v_path)); - fi_dirname = B->b_file == NULL ? "<none>" : - B->b_file->v_path == NULL ? "<unknown>" : - dirname(cleanpath(B->b_file->v_path)); - fi_pathname = B->b_file == NULL ? "<none>" : - B->b_file->v_path == NULL ? "<unknown>" : - cleanpath(B->b_file->v_path); - fi_offset = B->b_offset; - fi_fs = B->b_file == NULL ? "<none>" : - stringof(B->b_file->v_op->vnop_name); - fi_mount = B->b_file == NULL ? "<none>" : - B->b_file->v_vfsp->vfs_vnodecovered == NULL ? "/" : - B->b_file->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" : - cleanpath(B->b_file->v_vfsp->vfs_vnodecovered->v_path); - fi_oflags = 0; +translator bufinfo_t < struct bio *B > { + b_flags = B->bio_flags; + b_bcount = B->bio_bcount; + b_addr = B->bio_data; + b_blkno = 0; + b_lblkno = 0; + b_resid = B->bio_resid; + b_bufsize = 0; /* XXX gnn */ + b_error = B->bio_error; }; /* @@ -158,63 +94,17 @@ inline int O_APPEND = 0x0008; #pragma D binding "1.1" O_APPEND inline int O_CREAT = 0x0200; #pragma D binding "1.1" O_CREAT -inline int O_DSYNC = O_DSYNC; -#pragma D binding "1.1" O_DSYNC inline int O_EXCL = 0x0800; #pragma D binding "1.1" O_EXCL -inline int O_LARGEFILE = O_LARGEFILE; -#pragma D binding "1.1" O_LARGEFILE inline int O_NOCTTY = 0x8000; #pragma D binding "1.1" O_NOCTTY inline int O_NONBLOCK = 0x0004; #pragma D binding "1.1" O_NONBLOCK inline int O_NDELAY = 0x0004; #pragma D binding "1.1" O_NDELAY -inline int O_RSYNC = O_RSYNC; -#pragma D binding "1.1" O_RSYNC inline int O_SYNC = 0x0080; #pragma D binding "1.1" O_SYNC inline int O_TRUNC = 0x0400; #pragma D binding "1.1" O_TRUNC -inline int O_XATTR = O_XATTR; -#pragma D binding "1.1" O_XATTR - -#pragma D binding "1.1" translator -translator fileinfo_t < struct file *F > { - fi_name = F == NULL ? "<none>" : - F->f_vnode->v_path == NULL ? "<unknown>" : - basename(cleanpath(F->f_vnode->v_path)); - fi_dirname = F == NULL ? "<none>" : - F->f_vnode->v_path == NULL ? "<unknown>" : - dirname(cleanpath(F->f_vnode->v_path)); - fi_pathname = F == NULL ? "<none>" : - F->f_vnode->v_path == NULL ? "<unknown>" : - cleanpath(F->f_vnode->v_path); - fi_offset = F == NULL ? 0 : F->f_offset; - fi_fs = F == NULL ? "<none>" : stringof(F->f_vnode->v_op->vnop_name); - fi_mount = F == NULL ? "<none>" : - F->f_vnode->v_vfsp->vfs_vnodecovered == NULL ? "/" : - F->f_vnode->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" : - cleanpath(F->f_vnode->v_vfsp->vfs_vnodecovered->v_path); - fi_oflags = F == NULL ? 0 : F->f_flag + (int)FOPEN; -}; - -inline fileinfo_t fds[int fd] = xlate <fileinfo_t> ( - fd >= 0 && fd < curthread->t_procp->p_user.u_finfo.fi_nfiles ? - curthread->t_procp->p_user.u_finfo.fi_list[fd].uf_file : NULL); -#pragma D attributes Stable/Stable/Common fds -#pragma D binding "1.1" fds -#pragma D binding "1.2" translator -translator fileinfo_t < struct vnode *V > { - fi_name = V->v_path == NULL ? "<unknown>" : - basename(cleanpath(V->v_path)); - fi_dirname = V->v_path == NULL ? "<unknown>" : - dirname(cleanpath(V->v_path)); - fi_pathname = V->v_path == NULL ? "<unknown>" : cleanpath(V->v_path); - fi_fs = stringof(V->v_op->vnop_name); - fi_mount = V->v_vfsp->vfs_vnodecovered == NULL ? "/" : - V->v_vfsp->vfs_vnodecovered->v_path == NULL ? "<unknown>" : - cleanpath(V->v_vfsp->vfs_vnodecovered->v_path); -}; diff --git a/sys/kern/dtio_kdtrace.c b/sys/kern/dtio_kdtrace.c new file mode 100644 index 0000000..cfac370 --- /dev/null +++ b/sys/kern/dtio_kdtrace.c @@ -0,0 +1,232 @@ +/*- + * Copyright (c) 2012 Advanced Computing Technologies LLC + * Written by George Neville-Neil gnn@freebsd.org + * All rights reserved. + * + * 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 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 THE 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/module.h> + +#include <sys/dtrace.h> +#include "../sys/dtrace_bsd.h" + + +static int dtio_unload(void); +static void dtio_getargdesc(void *, dtrace_id_t, void *, + dtrace_argdesc_t *); +static void dtio_provide(void *, dtrace_probedesc_t *); +static void dtio_destroy(void *, dtrace_id_t, void *); +static void dtio_enable(void *, dtrace_id_t, void *); +static void dtio_disable(void *, dtrace_id_t, void *); +static void dtio_load(void *); + +static dtrace_pattr_t dtio_attr = { +{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, +{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, +{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, +{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, +{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, +}; + +static char *genunix = "genunix"; + +/* + * Name strings. + */ +static char *dtio_start_str = "start"; +static char *dtio_done_str = "done"; +static char *dtio_wait_start_str = "wait-start"; +static char *dtio_wait_done_str = "wait-done"; + +static dtrace_pops_t dtio_pops = { + dtio_provide, + NULL, + dtio_enable, + dtio_disable, + NULL, + NULL, + dtio_getargdesc, + NULL, + NULL, + dtio_destroy +}; + +static dtrace_provider_id_t dtio_id; + +extern uint32_t dtio_start_id; +extern uint32_t dtio_done_id; +extern uint32_t dtio_wait_start_id; +extern uint32_t dtio_wait_done_id; + +static void +dtio_getargdesc(void *arg, dtrace_id_t id, void *parg, + dtrace_argdesc_t *desc) +{ + const char *p = NULL; + + switch (desc->dtargd_ndx) { + case 0: + p = "struct bio *"; + break; + case 1: + p = "struct devstat *"; + break; + default: + desc->dtargd_ndx = DTRACE_ARGNONE; + } + + if (p != NULL) + strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native)); +} + +static void +dtio_provide(void *arg, dtrace_probedesc_t *desc) +{ + if (desc != NULL) + return; + + if (dtrace_probe_lookup(dtio_id, genunix, NULL, + dtio_start_str) == 0) { + dtio_start_id = dtrace_probe_create(dtio_id, genunix, NULL, + dtio_start_str, 0, NULL); + } + if (dtrace_probe_lookup(dtio_id, genunix, NULL, dtio_done_str) == 0) { + dtio_done_id = dtrace_probe_create(dtio_id, genunix, NULL, + dtio_done_str, 0, NULL); + } + if (dtrace_probe_lookup(dtio_id, genunix, NULL, + dtio_wait_start_str) == 0) { + dtio_wait_start_id = dtrace_probe_create(dtio_id, genunix, + NULL, + dtio_wait_start_str, + 0, NULL); + } + if (dtrace_probe_lookup(dtio_id, genunix, NULL, + dtio_wait_done_str) == 0) { + dtio_wait_done_id = dtrace_probe_create(dtio_id, genunix, NULL, + dtio_wait_done_str, 0, NULL); + } + +} + +static void +dtio_destroy(void *arg, dtrace_id_t id, void *parg) +{ +} + +static void +dtio_enable(void *arg, dtrace_id_t id, void *parg) +{ + if (id == dtio_start_id) + dtrace_io_start_probe = + (dtrace_io_start_probe_func_t)dtrace_probe; + else if (id == dtio_done_id) + dtrace_io_done_probe = + (dtrace_io_done_probe_func_t)dtrace_probe; + else if (id == dtio_wait_start_id) + dtrace_io_wait_start_probe = + (dtrace_io_wait_start_probe_func_t)dtrace_probe; + else if (id == dtio_wait_done_id) + dtrace_io_wait_done_probe = + (dtrace_io_wait_done_probe_func_t)dtrace_probe; + else + printf("dtrace io provider: unknown ID\n"); + +} + +static void +dtio_disable(void *arg, dtrace_id_t id, void *parg) +{ + if (id == dtio_start_id) + dtrace_io_start_probe = NULL; + else if (id == dtio_done_id) + dtrace_io_done_probe = NULL; + else if (id == dtio_wait_start_id) + dtrace_io_wait_start_probe = NULL; + else if (id == dtio_wait_done_id) + dtrace_io_wait_done_probe = NULL; + else + printf("dtrace io provider: unknown ID\n"); + +} + +static void +dtio_load(void *dummy) +{ + if (dtrace_register("io", &dtio_attr, DTRACE_PRIV_USER, NULL, + &dtio_pops, NULL, &dtio_id) != 0) + return; +} + + +static int +dtio_unload() +{ + dtrace_io_start_probe = NULL; + dtrace_io_done_probe = NULL; + dtrace_io_wait_start_probe = NULL; + dtrace_io_wait_done_probe = NULL; + + return (dtrace_unregister(dtio_id)); +} + +static int +dtio_modevent(module_t mod __unused, int type, void *data __unused) +{ + int error = 0; + + switch (type) { + case MOD_LOAD: + break; + + case MOD_UNLOAD: + break; + + case MOD_SHUTDOWN: + break; + + default: + error = EOPNOTSUPP; + break; + } + + return (error); +} + +SYSINIT(dtio_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, + dtio_load, NULL); +SYSUNINIT(dtio_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, + dtio_unload, NULL); + +DEV_MODULE(dtio, dtio_modevent, NULL); +MODULE_VERSION(dtio, 1); +MODULE_DEPEND(dtio, dtrace, 1, 1, 1); +MODULE_DEPEND(dtio, opensolaris, 1, 1, 1); diff --git a/sys/kern/subr_devstat.c b/sys/kern/subr_devstat.c index bbbfdbf..20e6e02 100644 --- a/sys/kern/subr_devstat.c +++ b/sys/kern/subr_devstat.c @@ -29,6 +29,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_kdtrace.h" + #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> @@ -44,6 +46,54 @@ __FBSDID("$FreeBSD$"); #include <machine/atomic.h> +#ifdef KDTRACE_HOOKS +#include <sys/dtrace_bsd.h> + +dtrace_io_start_probe_func_t dtrace_io_start_probe; +dtrace_io_done_probe_func_t dtrace_io_done_probe; +dtrace_io_wait_start_probe_func_t dtrace_io_wait_start_probe; +dtrace_io_wait_done_probe_func_t dtrace_io_wait_done_probe; + +uint32_t dtio_start_id; +uint32_t dtio_done_id; +uint32_t dtio_wait_start_id; +uint32_t dtio_wait_done_id; + +#define DTRACE_DEVSTAT_START() \ + if (dtrace_io_start_probe != NULL) \ + (*dtrace_io_start_probe)(dtio_start_id, NULL, ds); + +#define DTRACE_DEVSTAT_BIO_START() \ + if (dtrace_io_start_probe != NULL) \ + (*dtrace_io_start_probe)(dtio_start_id, bp, ds); + +#define DTRACE_DEVSTAT_DONE() \ + if (dtrace_io_done_probe != NULL) \ + (*dtrace_io_done_probe)(dtio_done_id, NULL, ds); + +#define DTRACE_DEVSTAT_BIO_DONE() \ + if (dtrace_io_done_probe != NULL) \ + (*dtrace_io_done_probe)(dtio_done_id, bp, ds); + +#define DTRACE_DEVSTAT_WAIT_START() \ + if (dtrace_io_wait_start_probe != NULL) \ + (*dtrace_io_wait_start_probe)(dtio_wait_start_id, NULL, ds); + +#define DTRACE_DEVSTAT_WAIT_DONE() \ + if (dtrace_io_wait_done_probe != NULL) \ + (*dtrace_io_wait_done_probe)(dtio_wait_done_id, NULL, ds); + +#else /* ! KDTRACE_HOOKS */ + +#define DTRACE_DEVSTAT_START() + +#define DTRACE_DEVSTAT_DONE() + +#define DTRACE_DEVSTAT_WAIT_START() + +#define DTRACE_DEVSTAT_WAIT_DONE() +#endif /* KDTRACE_HOOKS */ + static int devstat_num_devs; static long devstat_generation = 1; static int devstat_version = DEVSTAT_VERSION; @@ -227,6 +277,7 @@ devstat_start_transaction(struct devstat *ds, struct bintime *now) } ds->start_count++; atomic_add_rel_int(&ds->sequence0, 1); + DTRACE_DEVSTAT_START(); } void @@ -241,6 +292,7 @@ devstat_start_transaction_bio(struct devstat *ds, struct bio *bp) binuptime(&bp->bio_t0); devstat_start_transaction(ds, &bp->bio_t0); + DTRACE_DEVSTAT_BIO_START(); } /* @@ -312,6 +364,7 @@ devstat_end_transaction(struct devstat *ds, uint32_t bytes, ds->end_count++; atomic_add_rel_int(&ds->sequence0, 1); + DTRACE_DEVSTAT_DONE(); } void @@ -334,6 +387,7 @@ devstat_end_transaction_bio(struct devstat *ds, struct bio *bp) devstat_end_transaction(ds, bp->bio_bcount - bp->bio_resid, DEVSTAT_TAG_SIMPLE, flg, NULL, &bp->bio_t0); + DTRACE_DEVSTAT_BIO_DONE(); } /* diff --git a/sys/modules/dtrace/Makefile b/sys/modules/dtrace/Makefile index f8f3785..02423e9 100644 --- a/sys/modules/dtrace/Makefile +++ b/sys/modules/dtrace/Makefile @@ -9,6 +9,7 @@ SUBDIR= dtmalloc \ dtrace \ dtraceall \ dtrace_test \ + dtio \ prototype \ sdt \ systrace diff --git a/sys/modules/dtrace/dtio/Makefile b/sys/modules/dtrace/dtio/Makefile new file mode 100644 index 0000000..ff68ce4 --- /dev/null +++ b/sys/modules/dtrace/dtio/Makefile @@ -0,0 +1,13 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../kern + +KMOD= dtio +SRCS= dtio_kdtrace.c \ + vnode_if.h + +CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris \ + -I${.CURDIR}/../../../cddl/contrib/opensolaris/uts/common \ + -I${.CURDIR}/../../.. + +.include <bsd.kmod.mk> diff --git a/sys/modules/dtrace/dtraceall/dtraceall.c b/sys/modules/dtrace/dtraceall/dtraceall.c index 61896bf..9d7a23d 100644 --- a/sys/modules/dtrace/dtraceall/dtraceall.c +++ b/sys/modules/dtrace/dtraceall/dtraceall.c @@ -65,6 +65,7 @@ MODULE_VERSION(dtraceall, 1); MODULE_DEPEND(dtraceall, cyclic, 1, 1, 1); MODULE_DEPEND(dtraceall, opensolaris, 1, 1, 1); MODULE_DEPEND(dtraceall, dtrace, 1, 1, 1); +MODULE_DEPEND(dtraceall, dtio, 1, 1, 1); MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1); MODULE_DEPEND(dtraceall, dtnfscl, 1, 1, 1); MODULE_DEPEND(dtraceall, dtnfsclient, 1, 1, 1); diff --git a/sys/sys/dtrace_bsd.h b/sys/sys/dtrace_bsd.h index eb348b2..2198b26 100644 --- a/sys/sys/dtrace_bsd.h +++ b/sys/sys/dtrace_bsd.h @@ -38,6 +38,8 @@ struct thread; struct vattr; struct vnode; struct reg; +struct devstat; +struct bio; /* * Cyclic clock function type definition used to hook the cyclic @@ -168,6 +170,23 @@ extern dtrace_nfsclient_nfs23_done_probe_func_t extern dtrace_nfsclient_nfs23_done_probe_func_t dtrace_nfscl_nfs234_done_probe; +/* IO Provider hooks, really hook into devstat */ +typedef void (*dtrace_io_start_probe_func_t)(uint32_t, struct bio *, + struct devstat *); +extern dtrace_io_start_probe_func_t dtrace_io_start_probe; + +typedef void (*dtrace_io_done_probe_func_t)(uint32_t, struct bio *, + struct devstat *); +extern dtrace_io_done_probe_func_t dtrace_io_done_probe; + +typedef void (*dtrace_io_wait_start_probe_func_t)(uint32_t, uintptr_t *, + struct devstat *); +extern dtrace_io_wait_start_probe_func_t dtrace_io_wait_start_probe; + +typedef void (*dtrace_io_wait_done_probe_func_t)(uint32_t, uintptr_t *, + struct devstat *); +extern dtrace_io_wait_done_probe_func_t dtrace_io_wait_done_probe; + /* * Functions which allow the dtrace module to check that the kernel * hooks have been compiled with sufficient space for it's private |