]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Internal performance measurement support code.
authorKris Van Hees <kris.van.hees@oracle.com>
Fri, 19 Oct 2012 08:37:53 +0000 (04:37 -0400)
committerKris Van Hees <kris.van.hees@oracle.com>
Fri, 19 Oct 2012 08:37:53 +0000 (04:37 -0400)
The dt_perf provider implements a few probes that are used in performance
(or more accurately put, overhead) measurements.  It uses an ioctl()
interface to trigger N-count interations of invoking probes through
various mechanisms, and a probe to post the results back to userspace.
This code also adds an SDT probe in the DTrace kernel support code, just
to measure overhead for triggering trap based SDT probes.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
dtrace/dt_perf.h [new file with mode: 0644]
dtrace/dt_perf_dev.c [new file with mode: 0644]
dtrace/dt_perf_mod.c [new file with mode: 0644]

diff --git a/dtrace/dt_perf.h b/dtrace/dt_perf.h
new file mode 100644 (file)
index 0000000..d84352e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ * 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]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2011 Oracle, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DT_PERF_H_
+#define _DT_PERF_H_
+
+extern void dt_perf_provide(void *, const dtrace_probedesc_t *);
+extern int _dt_perf_enable(void *arg, dtrace_id_t, void *);
+extern void _dt_perf_disable(void *arg, dtrace_id_t, void *);
+extern void dt_perf_destroy(void *, dtrace_id_t, void *);
+
+extern dtrace_provider_id_t    dt_perf_id;
+
+extern int dt_perf_dev_init(void);
+extern void dt_perf_dev_exit(void);
+
+#endif /* _DT_PERF_H_ */
diff --git a/dtrace/dt_perf_dev.c b/dtrace/dt_perf_dev.c
new file mode 100644 (file)
index 0000000..36f9ca2
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * FILE:       dt_pref_dev.c
+ * DESCRIPTION:        DTrace Performance Test Probe: device file handling
+ *
+ * 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.
+ *
+ * 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]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2011 Oracle, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/miscdevice.h>
+#include <trace/syscall.h>
+#include <asm/unistd.h>
+
+#include "dtrace.h"
+#include "dtrace_dev.h"
+#include "dt_perf.h"
+
+static dtrace_id_t     invoke_pid = 0;
+static dtrace_id_t     result_pid = 0;
+static int             enabled = 0;
+
+void dt_perf_provide(void *arg, const dtrace_probedesc_t *desc)
+{
+       if (dtrace_probe_lookup(dt_perf_id, "dt_perf", NULL, "invoke") != 0)
+               return;
+
+       invoke_pid = dtrace_probe_create(dt_perf_id,
+                                 "dt_perf", NULL, "invoke", 0, NULL);
+       result_pid = dtrace_probe_create(dt_perf_id,
+                                 "dt_perf", NULL, "result", 0, NULL);
+}
+
+int _dt_perf_enable(void *arg, dtrace_id_t id, void *parg)
+{
+       enabled = 1;
+
+       return 0;
+}
+
+void _dt_perf_disable(void *arg, dtrace_id_t id, void *parg)
+{
+       enabled = 0;
+}
+
+void dt_perf_destroy(void *arg, dtrace_id_t id, void *parg)
+{
+}
+
+static long dt_perf_ioctl(struct file *file,
+                        unsigned int cmd, unsigned long arg)
+{
+       unsigned long   i;
+       ktime_t         tm0, tm1;
+
+       if (!enabled)
+               return -EAGAIN;
+
+       switch (cmd) {
+       case _IOW(1, 1, int):
+               tm0 = dtrace_gethrtime();
+               for (i = 0; i < arg; i++)
+                   dtrace_probe(invoke_pid, cmd, arg, 2, 3, 4);
+
+               tm1 = dtrace_gethrtime();
+               tm1.tv64 -= tm0.tv64;
+
+               dtrace_probe(result_pid, cmd, arg, tm1.tv64, tm1.tv64 >> 32, 0);
+               break;
+
+       case _IOW(1, 2, int): {
+               extern void dtrace_sdt_perf(void);
+
+               tm0 = dtrace_gethrtime();
+               for (i = 0; i < arg; i++)
+                   dtrace_sdt_perf();
+
+               tm1 = dtrace_gethrtime();
+               tm1.tv64 -= tm0.tv64;
+
+               dtrace_probe(result_pid, cmd, arg, tm1.tv64, tm1.tv64 >> 32, 0);
+               break;
+       }
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int dt_perf_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static int dt_perf_close(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static const struct file_operations dt_perf_fops = {
+       .owner  = THIS_MODULE,
+        .unlocked_ioctl = dt_perf_ioctl,
+        .open   = dt_perf_open,
+        .release = dt_perf_close,
+};
+
+static struct miscdevice dt_perf_dev = {
+       .minor = DT_DEV_DT_TEST_MINOR,
+       .name = "dt_perf",
+       .nodename = "dtrace/provider/dt_perf",
+       .fops = &dt_perf_fops,
+};
+
+int dt_perf_dev_init(void)
+{
+       int     ret = 0;
+
+       ret = misc_register(&dt_perf_dev);
+       if (ret)
+               pr_err("%s: Can't register misc device %d\n",
+                      dt_perf_dev.name, dt_perf_dev.minor);
+
+       return ret;
+}
+
+void dt_perf_dev_exit(void)
+{
+       misc_deregister(&dt_perf_dev);
+}
diff --git a/dtrace/dt_perf_mod.c b/dtrace/dt_perf_mod.c
new file mode 100644 (file)
index 0000000..18285ac
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * FILE:       dt_perf_mod.c
+ * DESCRIPTION:        DTrace Performance Test Probe: module handling
+ *
+ * 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.
+ *
+ * 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]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2011 Oracle, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <linux/module.h>
+
+#include "dtrace.h"
+#include "dtrace_dev.h"
+#include "dt_perf.h"
+
+MODULE_AUTHOR("Kris Van Hees (kris.van.hees@oracle.com)");
+MODULE_DESCRIPTION("DTrace Performance Test Probe");
+MODULE_VERSION("v0.1");
+MODULE_LICENSE("CDDL");
+
+static const dtrace_pattr_t dt_perf_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 },
+};
+
+DT_PROVIDER_POPS(dt_perf)
+
+static dtrace_pops_t dt_perf_pops = {
+       dt_perf_provide,
+       NULL,
+       dt_perf_enable,
+       dt_perf_disable,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       dt_perf_destroy
+};
+
+DT_PROVIDER_MODULE(dt_perf, DTRACE_PRIV_USER)