From owner-svn-src-head@FreeBSD.ORG Wed Jul 11 16:27:03 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 45920106566B; Wed, 11 Jul 2012 16:27:03 +0000 (UTC) (envelope-from gnn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2CB608FC18; Wed, 11 Jul 2012 16:27:03 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q6BGR3SU053296; Wed, 11 Jul 2012 16:27:03 GMT (envelope-from gnn@svn.freebsd.org) Received: (from gnn@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q6BGR2Gn053287; Wed, 11 Jul 2012 16:27:02 GMT (envelope-from gnn@svn.freebsd.org) Message-Id: <201207111627.q6BGR2Gn053287@svn.freebsd.org> From: "George V. Neville-Neil" Date: Wed, 11 Jul 2012 16:27:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r238366 - in head: cddl/lib/libdtrace sys/kern sys/modules/dtrace sys/modules/dtrace/dtio sys/modules/dtrace/dtraceall sys/sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Jul 2012 16:27:03 -0000 Author: gnn Date: Wed Jul 11 16:27:02 2012 New Revision: 238366 URL: http://svn.freebsd.org/changeset/base/238366 Log: 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 Added: head/sys/kern/dtio_kdtrace.c (contents, props changed) head/sys/modules/dtrace/dtio/ head/sys/modules/dtrace/dtio/Makefile (contents, props changed) Modified: head/cddl/lib/libdtrace/Makefile head/cddl/lib/libdtrace/io.d head/sys/kern/subr_devstat.c head/sys/modules/dtrace/Makefile head/sys/modules/dtrace/dtraceall/dtraceall.c head/sys/sys/dtrace_bsd.h Modified: head/cddl/lib/libdtrace/Makefile ============================================================================== --- head/cddl/lib/libdtrace/Makefile Wed Jul 11 15:04:20 2012 (r238365) +++ head/cddl/lib/libdtrace/Makefile Wed Jul 11 16:27:02 2012 (r238366) @@ -45,6 +45,7 @@ SRCS= dt_aggregate.c \ gmatch.c DSRCS= errno.d \ + io.d \ psinfo.d \ signal.d \ unistd.d Modified: head/cddl/lib/libdtrace/io.d ============================================================================== --- head/cddl/lib/libdtrace/io.d Wed Jul 11 15:04:20 2012 (r238365) +++ head/cddl/lib/libdtrace/io.d Wed Jul 11 16:27:02 2012 (r238366) @@ -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 ? "" : - 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 ? "" : - B->b_file->v_path == NULL ? "" : - basename(cleanpath(B->b_file->v_path)); - fi_dirname = B->b_file == NULL ? "" : - B->b_file->v_path == NULL ? "" : - dirname(cleanpath(B->b_file->v_path)); - fi_pathname = B->b_file == NULL ? "" : - B->b_file->v_path == NULL ? "" : - cleanpath(B->b_file->v_path); - fi_offset = B->b_offset; - fi_fs = B->b_file == NULL ? "" : - stringof(B->b_file->v_op->vnop_name); - fi_mount = B->b_file == NULL ? "" : - B->b_file->v_vfsp->vfs_vnodecovered == NULL ? "/" : - B->b_file->v_vfsp->vfs_vnodecovered->v_path == NULL ? "" : - 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 ? "" : - F->f_vnode->v_path == NULL ? "" : - basename(cleanpath(F->f_vnode->v_path)); - fi_dirname = F == NULL ? "" : - F->f_vnode->v_path == NULL ? "" : - dirname(cleanpath(F->f_vnode->v_path)); - fi_pathname = F == NULL ? "" : - F->f_vnode->v_path == NULL ? "" : - cleanpath(F->f_vnode->v_path); - fi_offset = F == NULL ? 0 : F->f_offset; - fi_fs = F == NULL ? "" : stringof(F->f_vnode->v_op->vnop_name); - fi_mount = F == NULL ? "" : - F->f_vnode->v_vfsp->vfs_vnodecovered == NULL ? "/" : - F->f_vnode->v_vfsp->vfs_vnodecovered->v_path == NULL ? "" : - 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 ( - 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 ? "" : - basename(cleanpath(V->v_path)); - fi_dirname = V->v_path == NULL ? "" : - dirname(cleanpath(V->v_path)); - fi_pathname = V->v_path == NULL ? "" : 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 ? "" : - cleanpath(V->v_vfsp->vfs_vnodecovered->v_path); -}; Added: head/sys/kern/dtio_kdtrace.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/kern/dtio_kdtrace.c Wed Jul 11 16:27:02 2012 (r238366) @@ -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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#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); Modified: head/sys/kern/subr_devstat.c ============================================================================== --- head/sys/kern/subr_devstat.c Wed Jul 11 15:04:20 2012 (r238365) +++ head/sys/kern/subr_devstat.c Wed Jul 11 16:27:02 2012 (r238366) @@ -29,6 +29,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_kdtrace.h" + #include #include #include @@ -44,6 +46,54 @@ __FBSDID("$FreeBSD$"); #include +#ifdef KDTRACE_HOOKS +#include + +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->start_count++; atomic_add_rel_int(&ds->sequence0, 1); + DTRACE_DEVSTAT_START(); } void @@ -241,6 +292,7 @@ devstat_start_transaction_bio(struct dev 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->end_count++; atomic_add_rel_int(&ds->sequence0, 1); + DTRACE_DEVSTAT_DONE(); } void @@ -334,6 +387,7 @@ devstat_end_transaction_bio(struct devst devstat_end_transaction(ds, bp->bio_bcount - bp->bio_resid, DEVSTAT_TAG_SIMPLE, flg, NULL, &bp->bio_t0); + DTRACE_DEVSTAT_BIO_DONE(); } /* Modified: head/sys/modules/dtrace/Makefile ============================================================================== --- head/sys/modules/dtrace/Makefile Wed Jul 11 15:04:20 2012 (r238365) +++ head/sys/modules/dtrace/Makefile Wed Jul 11 16:27:02 2012 (r238366) @@ -9,6 +9,7 @@ SUBDIR= dtmalloc \ dtrace \ dtraceall \ dtrace_test \ + dtio \ prototype \ sdt \ systrace Added: head/sys/modules/dtrace/dtio/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/modules/dtrace/dtio/Makefile Wed Jul 11 16:27:02 2012 (r238366) @@ -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 Modified: head/sys/modules/dtrace/dtraceall/dtraceall.c ============================================================================== --- head/sys/modules/dtrace/dtraceall/dtraceall.c Wed Jul 11 15:04:20 2012 (r238365) +++ head/sys/modules/dtrace/dtraceall/dtraceall.c Wed Jul 11 16:27:02 2012 (r238366) @@ -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); Modified: head/sys/sys/dtrace_bsd.h ============================================================================== --- head/sys/sys/dtrace_bsd.h Wed Jul 11 15:04:20 2012 (r238365) +++ head/sys/sys/dtrace_bsd.h Wed Jul 11 16:27:02 2012 (r238366) @@ -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 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