[PATCH linux dev-5.15] soc: aspeed: xdma: Add trace events

Eddie James eajames at linux.ibm.com
Wed Apr 13 07:53:31 AEST 2022


Trace the flow of the driver to aid debugging after an error.

Signed-off-by: Eddie James <eajames at linux.ibm.com>
---
 drivers/soc/aspeed/aspeed-xdma.c |  18 +++-
 include/trace/events/xdma.h      | 139 +++++++++++++++++++++++++++++++
 2 files changed, 155 insertions(+), 2 deletions(-)
 create mode 100644 include/trace/events/xdma.h

diff --git a/drivers/soc/aspeed/aspeed-xdma.c b/drivers/soc/aspeed/aspeed-xdma.c
index 48cfe30c90ad..579937ee3745 100644
--- a/drivers/soc/aspeed/aspeed-xdma.c
+++ b/drivers/soc/aspeed/aspeed-xdma.c
@@ -253,6 +253,9 @@ struct aspeed_xdma_client {
 	u32 size;
 };
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/xdma.h>
+
 static u32 aspeed_xdma_readl(struct aspeed_xdma *ctx, u8 reg)
 {
 	u32 v = readl(ctx->base + reg);
@@ -448,6 +451,7 @@ static int aspeed_xdma_start(struct aspeed_xdma *ctx, unsigned int num_cmds,
 
 	ctx->upstream = upstream;
 	for (i = 0; i < num_cmds; ++i) {
+		trace_xdma_start(ctx, &cmds[i]);
 		/*
 		 * Use memcpy_toio here to get some barriers before starting
 		 * the operation. The command(s) need to be in physical memory
@@ -490,6 +494,8 @@ static irqreturn_t aspeed_xdma_irq(int irq, void *arg)
 	spin_lock(&ctx->engine_lock);
 	status = aspeed_xdma_readl(ctx, ctx->chip->regs.status);
 
+	trace_xdma_irq(status);
+
 	if (status & ctx->chip->status_bits.ds_dirty) {
 		aspeed_xdma_done(ctx, true);
 	} else {
@@ -514,6 +520,8 @@ static void aspeed_xdma_reset(struct aspeed_xdma *ctx)
 {
 	unsigned long flags;
 
+	trace_xdma_reset(ctx);
+
 	reset_control_assert(ctx->reset);
 	usleep_range(XDMA_ENGINE_SETUP_TIME_MIN_US,
 		     XDMA_ENGINE_SETUP_TIME_MAX_US);
@@ -544,7 +552,7 @@ static irqreturn_t aspeed_xdma_pcie_irq(int irq, void *arg)
 {
 	struct aspeed_xdma *ctx = arg;
 
-	dev_dbg(ctx->dev, "PCI-E reset requested.\n");
+	trace_xdma_perst(ctx);
 
 	spin_lock(&ctx->engine_lock);
 	if (ctx->in_reset) {
@@ -682,6 +690,7 @@ static void aspeed_xdma_vma_close(struct vm_area_struct *vma)
 
 	gen_pool_free(client->ctx->pool, (unsigned long)client->virt,
 		      client->size);
+	trace_xdma_unmap(client);
 
 	client->virt = NULL;
 	client->phys = 0;
@@ -706,6 +715,7 @@ static int aspeed_xdma_mmap(struct file *file, struct vm_area_struct *vma)
 	client->virt = gen_pool_dma_alloc(ctx->pool, client->size,
 					  &client->phys);
 	if (!client->virt) {
+		trace_xdma_mmap_error(client, 0UL);
 		client->phys = 0;
 		client->size = 0;
 		return -ENOMEM;
@@ -725,12 +735,14 @@ static int aspeed_xdma_mmap(struct file *file, struct vm_area_struct *vma)
 		gen_pool_free(ctx->pool, (unsigned long)client->virt,
 			      client->size);
 
+		trace_xdma_mmap_error(client, vma->vm_start);
 		client->virt = NULL;
 		client->phys = 0;
 		client->size = 0;
 		return rc;
 	}
 
+	trace_xdma_mmap(client);
 	dev_dbg(ctx->dev, "mmap: v[%08lx] to p[%08x], s[%08x]\n",
 		vma->vm_start, (u32)client->phys, client->size);
 
@@ -776,9 +788,11 @@ static int aspeed_xdma_release(struct inode *inode, struct file *file)
 	if (reset)
 		aspeed_xdma_reset(ctx);
 
-	if (client->virt)
+	if (client->virt) {
 		gen_pool_free(ctx->pool, (unsigned long)client->virt,
 			      client->size);
+		trace_xdma_unmap(client);
+	}
 
 	kfree(client);
 	kobject_put(&ctx->kobj);
diff --git a/include/trace/events/xdma.h b/include/trace/events/xdma.h
new file mode 100644
index 000000000000..bf515ad3d8e5
--- /dev/null
+++ b/include/trace/events/xdma.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM xdma
+
+#if !defined(_TRACE_XDMA_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_XDMA_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(xdma_start,
+	TP_PROTO(const struct aspeed_xdma *ctx, const struct aspeed_xdma_cmd *cmd),
+	TP_ARGS(ctx, cmd),
+	TP_STRUCT__entry(
+		__field(bool,	dir_upstream)
+		__field(unsigned int,	index)
+		__field(__u64,	host)
+		__field(__u64,	pitch)
+		__field(__u64,	cmd)
+	),
+	TP_fast_assign(
+		__entry->dir_upstream = ctx->upstream;
+		__entry->index = ctx->cmd_idx;
+		__entry->host = cmd->host_addr;
+		__entry->pitch = cmd->pitch;
+		__entry->cmd = cmd->cmd;
+	),
+	TP_printk("%s cmd:%u [%08llx %016llx %016llx]",
+		__entry->dir_upstream ? "upstream" : "downstream",
+		__entry->index,
+		__entry->host,
+		__entry->pitch,
+		__entry->cmd
+	)
+);
+
+TRACE_EVENT(xdma_irq,
+	TP_PROTO(u32 sts),
+	TP_ARGS(sts),
+	TP_STRUCT__entry(
+		__field(__u32,	status)
+	),
+	TP_fast_assign(
+		__entry->status = sts;
+	),
+	TP_printk("sts:%08x",
+		__entry->status
+	)
+);
+
+TRACE_EVENT(xdma_reset,
+	TP_PROTO(const struct aspeed_xdma *ctx),
+	TP_ARGS(ctx),
+	TP_STRUCT__entry(
+		__field(bool,	dir_upstream)
+		__field(bool,	in_progress)
+	),
+	TP_fast_assign(
+		__entry->dir_upstream = ctx->upstream;
+		__entry->in_progress =
+			ctx->current_client ? ctx->current_client->in_progress : false;
+	),
+	TP_printk("%sin progress%s",
+		__entry->in_progress ? "" : "not ",
+		__entry->in_progress ? (__entry->dir_upstream ? " upstream" : " downstream") : ""
+	)
+);
+
+TRACE_EVENT(xdma_perst,
+	TP_PROTO(const struct aspeed_xdma *ctx),
+	TP_ARGS(ctx),
+	TP_STRUCT__entry(
+		__field(bool,	in_reset)
+	),
+	TP_fast_assign(
+		__entry->in_reset = ctx->in_reset;
+	),
+	TP_printk("%s",
+		__entry->in_reset ? "in reset" : ""
+	)
+);
+
+TRACE_EVENT(xdma_unmap,
+	TP_PROTO(const struct aspeed_xdma_client *client),
+	TP_ARGS(client),
+	TP_STRUCT__entry(
+		__field(__u32,	phys)
+		__field(__u32,	size)
+	),
+	TP_fast_assign(
+		__entry->phys = client->phys;
+		__entry->size = client->size;
+	),
+	TP_printk("p:%08x s:%08x",
+		__entry->phys,
+		__entry->size
+	)
+);
+
+TRACE_EVENT(xdma_mmap_error,
+	TP_PROTO(const struct aspeed_xdma_client *client, unsigned long vm_start),
+	TP_ARGS(client, vm_start),
+	TP_STRUCT__entry(
+		__field(__u32,	phys)
+		__field(__u32,	size)
+		__field(unsigned long,	vm_start)
+	),
+	TP_fast_assign(
+		__entry->phys = client->phys;
+		__entry->size = client->size;
+		__entry->vm_start = vm_start;
+	),
+	TP_printk("p:%08x s:%08x v:%08lx",
+		__entry->phys,
+		__entry->size,
+		__entry->vm_start
+	)
+);
+
+TRACE_EVENT(xdma_mmap,
+	TP_PROTO(const struct aspeed_xdma_client *client),
+	TP_ARGS(client),
+	TP_STRUCT__entry(
+		__field(__u32,	phys)
+		__field(__u32,	size)
+	),
+	TP_fast_assign(
+		__entry->phys = client->phys;
+		__entry->size = client->size;
+	),
+	TP_printk("p:%08x s:%08x",
+		__entry->phys,
+		__entry->size
+	)
+);
+
+#endif /* _TRACE_XDMA_H */
+
+#include <trace/define_trace.h>
-- 
2.27.0



More information about the openbmc mailing list