From dfca0a2147908acaaadf77e916fac9a423b76fa8 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Tue, 22 Nov 2011 09:48:03 +0200 Subject: video: tegra: host: Add syncpt and cmdbuf to trace Add sync point information and contents of command buffers to ftrace output. Change-Id: Ie30e2208da3f76315e6d706c841190eff22dd09d Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/66072 Tested-by: Gerrit_Virtual_Submit Reviewed-by: Yu-Huan Hsu Rebase-Id: Rcb8cda3b5720036e28b112558baa0f4d2b37a7a8 --- drivers/video/tegra/host/debug.c | 3 ++ drivers/video/tegra/host/debug.h | 1 + drivers/video/tegra/host/dev.c | 45 ++++++++++++++-- include/trace/events/nvhost.h | 109 ++++++++++++++++++++++++++++++--------- 4 files changed, 132 insertions(+), 26 deletions(-) diff --git a/drivers/video/tegra/host/debug.c b/drivers/video/tegra/host/debug.c index 4659a97ac110..aa4b41d96574 100644 --- a/drivers/video/tegra/host/debug.c +++ b/drivers/video/tegra/host/debug.c @@ -26,6 +26,7 @@ #include "debug.h" pid_t nvhost_debug_null_kickoff_pid; +unsigned int nvhost_debug_trace_cmdbuf; pid_t nvhost_debug_force_timeout_pid; u32 nvhost_debug_force_timeout_val; @@ -130,6 +131,8 @@ void nvhost_debug_init(struct nvhost_master *master) debugfs_create_u32("null_kickoff_pid", S_IRUGO|S_IWUSR, de, &nvhost_debug_null_kickoff_pid); + debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR, de, + &nvhost_debug_trace_cmdbuf); if (master->op.debug.debug_init) master->op.debug.debug_init(de); diff --git a/drivers/video/tegra/host/debug.h b/drivers/video/tegra/host/debug.h index 0e9e51e5f955..9dd3a1995478 100644 --- a/drivers/video/tegra/host/debug.h +++ b/drivers/video/tegra/host/debug.h @@ -46,5 +46,6 @@ void nvhost_debug_output(struct output *o, const char* fmt, ...); extern pid_t nvhost_debug_force_timeout_pid; extern u32 nvhost_debug_force_timeout_val; extern u32 nvhost_debug_force_timeout_channel; +extern unsigned int nvhost_debug_trace_cmdbuf; #endif /*__NVHOST_DEBUG_H */ diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c index b552d5c52606..1767e53ca884 100644 --- a/drivers/video/tegra/host/dev.c +++ b/drivers/video/tegra/host/dev.c @@ -47,6 +47,7 @@ #define DRIVER_NAME "tegra_grhost" #define IFACE_NAME "nvhost" +#define TRACE_MAX_LENGTH 128U static int nvhost_major = NVHOST_MAJOR; static int nvhost_minor; @@ -74,6 +75,40 @@ struct nvhost_ctrl_userctx { u32 *mod_locks; }; +/* + * Write cmdbuf to ftrace output. Checks if cmdbuf contents should be output + * and mmaps the cmdbuf contents if required. + */ +static void trace_write_cmdbuf(const char *name, u32 mem_id, + u32 words, u32 offset) +{ + struct nvmap_handle_ref handle; + void *mem = NULL; + + if (nvhost_debug_trace_cmdbuf) { + handle.handle = nvmap_id_to_handle(mem_id); + mem = nvmap_mmap(&handle); + if (IS_ERR_OR_NULL(mem)) + mem = NULL; + }; + + trace_nvhost_channel_write_cmdbuf(name, mem_id, words, offset); + if (mem) { + u32 i; + /* + * Write in batches of 128 as there seems to be a limit of how + * much you can output to ftrace at once. + */ + for (i = 0; i < words; i += TRACE_MAX_LENGTH) { + trace_nvhost_channel_write_cmdbuf_data(name, mem_id, + min(words - i, TRACE_MAX_LENGTH), + offset + i * sizeof(u32), + mem); + } + nvmap_munmap(&handle, mem); + } +} + static int nvhost_channelrelease(struct inode *inode, struct file *filp) { struct nvhost_channel_userctx *priv = filp->private_data; @@ -218,7 +253,8 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, if (err) break; trace_nvhost_channel_write_submit(priv->ch->desc->name, - count, priv->hdr.num_cmdbufs, priv->hdr.num_relocs); + count, priv->hdr.num_cmdbufs, priv->hdr.num_relocs, + priv->hdr.syncpt_id, priv->hdr.syncpt_incrs); } else if (priv->hdr.num_cmdbufs) { struct nvhost_cmdbuf cmdbuf; consumed = sizeof(cmdbuf); @@ -228,7 +264,7 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, err = -EFAULT; break; } - trace_nvhost_channel_write_cmdbuf(priv->ch->desc->name, + trace_write_cmdbuf(priv->ch->desc->name, cmdbuf.mem, cmdbuf.words, cmdbuf.offset); add_gather(priv, cmdbuf.mem, cmdbuf.words, cmdbuf.offset); @@ -407,7 +443,8 @@ static long nvhost_channelctl(struct file *filp, trace_nvhost_ioctl_channel_submit(priv->ch->desc->name, priv->hdr.submit_version, priv->hdr.num_cmdbufs, priv->hdr.num_relocs, - priv->hdr.num_waitchks); + priv->hdr.num_waitchks, + priv->hdr.syncpt_id, priv->hdr.syncpt_incrs); break; } case NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS: @@ -616,6 +653,8 @@ static int nvhost_ioctl_ctrl_module_regrdwr( void *values = args->values; u32 vals[64]; + trace_nvhost_ioctl_ctrl_module_regrdwr(args->id, + args->num_offsets, args->write); if (!(args->id < ctx->dev->nb_modules) || (num_offsets == 0)) return -EINVAL; diff --git a/include/trace/events/nvhost.h b/include/trace/events/nvhost.h index 2a1845950ed5..a0184440a09c 100644 --- a/include/trace/events/nvhost.h +++ b/include/trace/events/nvhost.h @@ -53,15 +53,18 @@ DEFINE_EVENT(nvhost, nvhost_ioctl_channel_flush, ); TRACE_EVENT(nvhost_channel_write_submit, - TP_PROTO(const char *name, ssize_t count, u32 cmdbufs, u32 relocs), + TP_PROTO(const char *name, ssize_t count, u32 cmdbufs, u32 relocs, + u32 syncpt_id, u32 syncpt_incrs), - TP_ARGS(name, count, cmdbufs, relocs), + TP_ARGS(name, count, cmdbufs, relocs, syncpt_id, syncpt_incrs), TP_STRUCT__entry( __field(const char *, name) __field(ssize_t, count) __field(u32, cmdbufs) __field(u32, relocs) + __field(u32, syncpt_id) + __field(u32, syncpt_incrs) ), TP_fast_assign( @@ -69,18 +72,21 @@ TRACE_EVENT(nvhost_channel_write_submit, __entry->count = count; __entry->cmdbufs = cmdbufs; __entry->relocs = relocs; + __entry->syncpt_id = syncpt_id; + __entry->syncpt_incrs = syncpt_incrs; ), - TP_printk("name=%s, count=%lu, cmdbufs=%lu, relocs=%ld", - __entry->name, (unsigned long)__entry->count, - (unsigned long)__entry->cmdbufs, (unsigned long)__entry->relocs) + TP_printk("name=%s, count=%d, cmdbufs=%u, relocs=%u, syncpt_id=%u, syncpt_incrs=%u", + __entry->name, __entry->count, __entry->cmdbufs, __entry->relocs, + __entry->syncpt_id, __entry->syncpt_incrs) ); TRACE_EVENT(nvhost_ioctl_channel_submit, TP_PROTO(const char *name, u32 version, u32 cmdbufs, u32 relocs, - u32 waitchks), + u32 waitchks, u32 syncpt_id, u32 syncpt_incrs), - TP_ARGS(name, version, cmdbufs, relocs, waitchks), + TP_ARGS(name, version, cmdbufs, relocs, waitchks, + syncpt_id, syncpt_incrs), TP_STRUCT__entry( __field(const char *, name) @@ -88,6 +94,8 @@ TRACE_EVENT(nvhost_ioctl_channel_submit, __field(u32, cmdbufs) __field(u32, relocs) __field(u32, waitchks) + __field(u32, syncpt_id) + __field(u32, syncpt_incrs) ), TP_fast_assign( @@ -96,16 +104,18 @@ TRACE_EVENT(nvhost_ioctl_channel_submit, __entry->cmdbufs = cmdbufs; __entry->relocs = relocs; __entry->waitchks = waitchks; + __entry->syncpt_id = syncpt_id; + __entry->syncpt_incrs = syncpt_incrs; ), - TP_printk("name=%s, version=%lu, cmdbufs=%lu, relocs=%ld, waitchks=%ld", - __entry->name, (unsigned long)__entry->version, - (unsigned long)__entry->cmdbufs, (unsigned long)__entry->relocs, - (unsigned long)__entry->waitchks) + TP_printk("name=%s, version=%u, cmdbufs=%u, relocs=%u, waitchks=%u, syncpt_id=%u, syncpt_incrs=%u", + __entry->name, __entry->version, __entry->cmdbufs, __entry->relocs, + __entry->waitchks, __entry->syncpt_id, __entry->syncpt_incrs) ); TRACE_EVENT(nvhost_channel_write_cmdbuf, - TP_PROTO(const char *name, u32 mem_id, u32 words, u32 offset), + TP_PROTO(const char *name, u32 mem_id, + u32 words, u32 offset), TP_ARGS(name, mem_id, words, offset), @@ -123,9 +133,43 @@ TRACE_EVENT(nvhost_channel_write_cmdbuf, __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) + TP_printk("name=%s, mem_id=%08x, words=%u, offset=%d", + __entry->name, __entry->mem_id, + __entry->words, __entry->offset) +); + +TRACE_EVENT(nvhost_channel_write_cmdbuf_data, + TP_PROTO(const char *name, u32 mem_id, + u32 words, u32 offset, void *cmdbuf), + + TP_ARGS(name, mem_id, words, offset, cmdbuf), + + TP_STRUCT__entry( + __field(const char *, name) + __field(u32, mem_id) + __field(u32, words) + __field(u32, offset) + __field(bool, cmdbuf) + __dynamic_array(u32, cmdbuf, words) + ), + + TP_fast_assign( + if (cmdbuf) { + memcpy(__get_dynamic_array(cmdbuf), cmdbuf+offset, + words * sizeof(u32)); + } + __entry->cmdbuf = cmdbuf; + __entry->name = name; + __entry->mem_id = mem_id; + __entry->words = words; + __entry->offset = offset; + ), + + TP_printk("name=%s, mem_id=%08x, words=%u, offset=%d, contents=[%s]", + __entry->name, __entry->mem_id, + __entry->words, __entry->offset, + __print_hex(__get_dynamic_array(cmdbuf), + __entry->cmdbuf ? __entry->words * 4 : 0)) ); TRACE_EVENT(nvhost_channel_write_relocs, @@ -143,8 +187,8 @@ TRACE_EVENT(nvhost_channel_write_relocs, __entry->relocs = relocs; ), - TP_printk("name=%s, relocs=%lu", - __entry->name, (unsigned long)__entry->relocs) + TP_printk("name=%s, relocs=%u", + __entry->name, __entry->relocs) ); TRACE_EVENT(nvhost_channel_write_waitchks, @@ -164,9 +208,8 @@ TRACE_EVENT(nvhost_channel_write_waitchks, __entry->waitmask = waitmask; ), - TP_printk("name=%s, waitchks=%lu, waitmask=%08lx", - __entry->name, (unsigned long)__entry->waitchks, - (unsigned long)__entry->waitmask) + TP_printk("name=%s, waitchks=%u, waitmask=%08x", + __entry->name, __entry->waitchks, __entry->waitmask) ); TRACE_EVENT(nvhost_channel_context_switch, @@ -186,9 +229,8 @@ TRACE_EVENT(nvhost_channel_context_switch, __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) + TP_printk("name=%s, old=%p, new=%p", + __entry->name, __entry->old_ctx, __entry->new_ctx) ); TRACE_EVENT(nvhost_ctrlopen, @@ -287,6 +329,27 @@ TRACE_EVENT(nvhost_ioctl_ctrl_syncpt_wait, __entry->id, __entry->threshold, __entry->timeout) ); +TRACE_EVENT(nvhost_ioctl_ctrl_module_regrdwr, + TP_PROTO(u32 id, u32 num_offsets, bool write), + + TP_ARGS(id, num_offsets, write), + + TP_STRUCT__entry( + __field(u32, id) + __field(u32, num_offsets) + __field(bool, write) + ), + + TP_fast_assign( + __entry->id = id; + __entry->num_offsets = num_offsets; + __entry->write = write; + ), + + TP_printk("id=%u, num_offsets=%u, write=%d", + __entry->id, __entry->num_offsets, __entry->write) +); + TRACE_EVENT(nvhost_channel_submitted, TP_PROTO(const char *name, u32 syncpt_base, u32 syncpt_max), -- cgit v1.2.3