Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jul 2012 16:27:02 +0000 (UTC)
From:      "George V. Neville-Neil" <gnn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r238366 - in head: cddl/lib/libdtrace sys/kern sys/modules/dtrace sys/modules/dtrace/dtio sys/modules/dtrace/dtraceall sys/sys
Message-ID:  <201207111627.q6BGR2Gn053287@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 ? "<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);
-};

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 <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);

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 <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->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 <bsd.kmod.mk>

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207111627.q6BGR2Gn053287>