nvhost: Add tracing to nvhost driver.
Terje Bergstrom [Thu, 28 Apr 2011 13:32:33 +0000 (16:32 +0300)]
Creates /d/tracing/events/nvhost. Logs channel opens, closes,
writes and flushes. For writes, logs number, size and address
of cmdbufs and number of relocs.

Original-Change-Id: I5bdadcb40c31e3f057eb8c4579b95e235d860e39
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/29770
Reviewed-by: Andrew Howe <ahowe@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Reviewed-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>

Rebase-Id: Rbe763a4da9f5c431170301f91fa1bc4cb4ed8f0e

arch/arm/mach-tegra/include/trace/events/nvhost.h [new file with mode: 0644]
drivers/video/tegra/host/dev.c
drivers/video/tegra/host/nvhost_channel.c

diff --git a/arch/arm/mach-tegra/include/trace/events/nvhost.h b/arch/arm/mach-tegra/include/trace/events/nvhost.h
new file mode 100644 (file)
index 0000000..2d5839f
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * include/trace/events/nvhost.h
+ *
+ * Nvhost event logging to ftrace.
+ *
+ * Copyright (c) 2010, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM nvhost
+
+#if !defined(_TRACE_NVHOST_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_NVHOST_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(nvhost,
+       TP_PROTO(const char *name),
+       TP_ARGS(name),
+       TP_STRUCT__entry(__field(const char *, name)),
+       TP_fast_assign(__entry->name = name;),
+       TP_printk("name=%s", __entry->name)
+);
+
+DEFINE_EVENT(nvhost, nvhost_channel_open,
+       TP_PROTO(const char *name),
+       TP_ARGS(name)
+);
+
+DEFINE_EVENT(nvhost, nvhost_channel_release,
+       TP_PROTO(const char *name),
+       TP_ARGS(name)
+);
+
+DEFINE_EVENT(nvhost, nvhost_ioctl_channel_flush,
+       TP_PROTO(const char *name),
+       TP_ARGS(name)
+);
+
+TRACE_EVENT(nvhost_channel_write_submit,
+       TP_PROTO(const char *name, ssize_t count, u32 cmdbufs, u32 relocs),
+
+       TP_ARGS(name, count, cmdbufs, relocs),
+
+       TP_STRUCT__entry(
+               __field(const char *, name)
+               __field(ssize_t, count)
+               __field(u32, cmdbufs)
+               __field(u32, relocs)
+       ),
+
+       TP_fast_assign(
+               __entry->name = name;
+               __entry->count = count;
+               __entry->cmdbufs = cmdbufs;
+               __entry->relocs = relocs;
+       ),
+
+       TP_printk("name=%s, count=%lu, cmdbufs=%lu, relocs=%ld",
+         __entry->name, (unsigned long)__entry->count,
+         (unsigned long)__entry->cmdbufs, (unsigned long)__entry->relocs)
+);
+
+TRACE_EVENT(nvhost_channel_write_cmdbuf,
+       TP_PROTO(const char *name, u32 mem_id, u32 words, u32 offset),
+
+       TP_ARGS(name, mem_id, words, offset),
+
+       TP_STRUCT__entry(
+               __field(const char *, name)
+               __field(u32, mem_id)
+               __field(u32, words)
+               __field(u32, offset)
+       ),
+
+       TP_fast_assign(
+               __entry->name = name;
+               __entry->mem_id = mem_id;
+               __entry->words = words;
+               __entry->offset = offset;
+       ),
+
+       TP_printk("name=%s, mem_id=%08lx, words=%lu, offset=%ld",
+         __entry->name, (unsigned long)__entry->mem_id,
+         (unsigned long)__entry->words, (unsigned long)__entry->offset)
+);
+
+TRACE_EVENT(nvhost_channel_write_relocs,
+       TP_PROTO(const char *name, u32 relocs),
+
+       TP_ARGS(name, relocs),
+
+       TP_STRUCT__entry(
+               __field(const char *, name)
+               __field(u32, relocs)
+       ),
+
+       TP_fast_assign(
+               __entry->name = name;
+               __entry->relocs = relocs;
+       ),
+
+       TP_printk("name=%s, relocs=%lu",
+         __entry->name, (unsigned long)__entry->relocs)
+);
+
+TRACE_EVENT(nvhost_channel_context_switch,
+       TP_PROTO(const char *name, void *old_ctx, void *new_ctx),
+
+       TP_ARGS(name, old_ctx, new_ctx),
+
+       TP_STRUCT__entry(
+           __field(const char *, name)
+           __field(void*, old_ctx)
+           __field(void*, new_ctx)
+       ),
+
+       TP_fast_assign(
+           __entry->name = name;
+           __entry->old_ctx = old_ctx;
+           __entry->new_ctx = new_ctx;
+       ),
+
+       TP_printk("name=%s, old=%08lx, new=%08lx",
+         __entry->name, (long unsigned int)__entry->old_ctx,
+         (long unsigned int)__entry->new_ctx)
+);
+
+TRACE_EVENT(nvhost_ctrlopen,
+       TP_PROTO(const char *name),
+       TP_ARGS(name),
+       TP_STRUCT__entry(
+           __field(const char *, name)
+       ),
+       TP_fast_assign(
+           __entry->name = name
+       ),
+       TP_printk("name=%s", __entry->name)
+);
+
+TRACE_EVENT(nvhost_ctrlrelease,
+       TP_PROTO(const char *name),
+       TP_ARGS(name),
+       TP_STRUCT__entry(
+           __field(const char *, name)
+       ),
+       TP_fast_assign(
+           __entry->name = name
+       ),
+       TP_printk("name=%s", __entry->name)
+);
+
+TRACE_EVENT(nvhost_ioctl_ctrl_module_mutex,
+       TP_PROTO(u32 lock, u32 id),
+
+       TP_ARGS(lock, id),
+
+       TP_STRUCT__entry(
+           __field(u32, lock);
+           __field(u32, id);
+       ),
+
+       TP_fast_assign(
+               __entry->lock = lock;
+               __entry->id = id;
+       ),
+
+       TP_printk("lock=%u, id=%d",
+               __entry->lock, __entry->id)
+       );
+
+TRACE_EVENT(nvhost_ioctl_ctrl_syncpt_incr,
+       TP_PROTO(u32 id),
+
+       TP_ARGS(id),
+
+       TP_STRUCT__entry(
+           __field(u32, id);
+       ),
+
+       TP_fast_assign(
+          __entry->id = id;
+       ),
+
+       TP_printk("id=%d", __entry->id)
+);
+
+TRACE_EVENT(nvhost_ioctl_ctrl_syncpt_read,
+       TP_PROTO(u32 id),
+
+       TP_ARGS(id),
+
+       TP_STRUCT__entry(
+           __field(u32, id);
+       ),
+
+       TP_fast_assign(
+               __entry->id = id;
+       ),
+
+       TP_printk("id=%d", __entry->id)
+);
+
+TRACE_EVENT(nvhost_ioctl_ctrl_syncpt_wait,
+       TP_PROTO(u32 id, u32 threshold, s32 timeout),
+
+       TP_ARGS(id, threshold, timeout),
+
+       TP_STRUCT__entry(
+               __field(u32, id)
+               __field(u32, threshold)
+               __field(s32, timeout)
+       ),
+
+       TP_fast_assign(
+               __entry->id = id;
+               __entry->threshold = threshold;
+               __entry->timeout = timeout;
+       ),
+
+       TP_printk("id=%u, threshold=%u, timeout=%d",
+         __entry->id, __entry->threshold, __entry->timeout)
+);
+
+#endif /*  _TRACE_NVHOST_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index 491908b..cb41827 100644 (file)
@@ -31,6 +31,9 @@
 #include <linux/uaccess.h>
 #include <linux/file.h>
 #include <linux/clk.h>
+#include <linux/hrtimer.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/nvhost.h>
 
 #include <asm/io.h>
 
@@ -68,6 +71,8 @@ static int nvhost_channelrelease(struct inode *inode, struct file *filp)
 {
        struct nvhost_channel_userctx *priv = filp->private_data;
 
+       trace_nvhost_channel_release(priv->ch->desc->name);
+
        filp->private_data = NULL;
 
        nvhost_putchannel(priv->ch, priv->hwctx);
@@ -91,10 +96,12 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp)
        struct nvhost_channel_userctx *priv;
        struct nvhost_channel *ch;
 
+
        ch = container_of(inode->i_cdev, struct nvhost_channel, cdev);
        ch = nvhost_getchannel(ch);
        if (!ch)
                return -ENOMEM;
+       trace_nvhost_channel_open(ch->desc->name);
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
@@ -164,6 +171,8 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
                                err = -EFAULT;
                                break;
                        }
+                       trace_nvhost_channel_write_submit(priv->ch->desc->name,
+                         count, priv->cmdbufs_pending, priv->relocs_pending);
                        priv->cur_gather = priv->gathers;
                        priv->pinarray_size = 0;
                } else if (priv->cmdbufs_pending) {
@@ -175,6 +184,8 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
                                err = -EFAULT;
                                break;
                        }
+                       trace_nvhost_channel_write_cmdbuf(priv->ch->desc->name,
+                         cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
                        add_gather(priv,
                                cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
                        priv->cmdbufs_pending--;
@@ -189,6 +200,8 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
                                err = -EFAULT;
                                break;
                        }
+                       trace_nvhost_channel_write_relocs(priv->ch->desc->name,
+                         numrelocs);
                        priv->pinarray_size += numrelocs;
                        priv->relocs_pending -= numrelocs;
                } else {
@@ -217,6 +230,8 @@ static int nvhost_ioctl_channel_flush(
        int num_unpin;
        int err;
 
+       trace_nvhost_ioctl_channel_flush(ctx->ch->desc->name);
+
        if (ctx->relocs_pending || ctx->cmdbufs_pending) {
                reset_submit(ctx);
                dev_err(device, "channel submit out of sync\n");
@@ -330,6 +345,8 @@ static int nvhost_ctrlrelease(struct inode *inode, struct file *filp)
        struct nvhost_ctrl_userctx *priv = filp->private_data;
        int i;
 
+       trace_nvhost_ctrlrelease(priv->dev->mod.name);
+
        filp->private_data = NULL;
        if (priv->mod_locks[0])
                nvhost_module_idle(&priv->dev->mod);
@@ -345,6 +362,8 @@ static int nvhost_ctrlopen(struct inode *inode, struct file *filp)
        struct nvhost_master *host = container_of(inode->i_cdev, struct nvhost_master, cdev);
        struct nvhost_ctrl_userctx *priv;
 
+       trace_nvhost_ctrlopen(host->mod.name);
+
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
@@ -360,6 +379,7 @@ static int nvhost_ioctl_ctrl_syncpt_read(
 {
        if (args->id >= NV_HOST1X_SYNCPT_NB_PTS)
                return -EINVAL;
+       trace_nvhost_ioctl_ctrl_syncpt_read(args->id);
        args->value = nvhost_syncpt_read(&ctx->dev->syncpt, args->id);
        return 0;
 }
@@ -370,6 +390,7 @@ static int nvhost_ioctl_ctrl_syncpt_incr(
 {
        if (args->id >= NV_HOST1X_SYNCPT_NB_PTS)
                return -EINVAL;
+       trace_nvhost_ioctl_ctrl_syncpt_incr(args->id);
        nvhost_syncpt_incr(&ctx->dev->syncpt, args->id);
        return 0;
 }
@@ -386,6 +407,8 @@ static int nvhost_ioctl_ctrl_syncpt_wait(
        else
                timeout = (u32)msecs_to_jiffies(args->timeout);
 
+       trace_nvhost_ioctl_ctrl_syncpt_wait(args->id, args->thresh,
+         args->timeout);
        return nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id,
                                        args->thresh, timeout);
 }
@@ -399,6 +422,7 @@ static int nvhost_ioctl_ctrl_module_mutex(
            args->lock > 1)
                return -EINVAL;
 
+       trace_nvhost_ioctl_ctrl_module_mutex(args->lock, args->id);
        if (args->lock && !ctx->mod_locks[args->id]) {
                if (args->id == 0)
                        nvhost_module_busy(&ctx->dev->mod);
index 71695cf..68caff5 100644 (file)
@@ -23,6 +23,7 @@
 #include "nvhost_channel.h"
 #include "dev.h"
 #include "nvhost_hwctx.h"
+#include <trace/events/nvhost.h>
 
 #include <linux/platform_device.h>
 
@@ -202,6 +203,8 @@ int nvhost_channel_submit(struct nvhost_channel *channel,
 
        /* context switch */
        if (channel->cur_ctx != hwctx) {
+               trace_nvhost_channel_context_switch(channel->desc->name,
+                 channel->cur_ctx, hwctx);
                hwctx_to_save = channel->cur_ctx;
                if (hwctx_to_save) {
                        syncpt_incrs += hwctx_to_save->save_incrs;