All of lore.kernel.org
 help / color / mirror / Atom feed
* [5/6] dma: tegra: add tracepoints to driver
@ 2018-11-07 10:02 Ben Dooks
  0 siblings, 0 replies; 5+ messages in thread
From: Ben Dooks @ 2018-11-07 10:02 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: dan.j.williams, vkoul, ldewangan, dmaengine, linux-tegra, Ingo Molnar

On 2018-10-12 18:01, Steven Rostedt wrote:
> On Fri, 12 Oct 2018 10:44:53 +0100
> Ben Dooks <ben.dooks@codethink.co.uk> wrote:
> 
>> Add some trace-points to the driver to allow for debuging via the
>> trace pipe.
>> 
>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>> ---
>> Cc: Ingo Molnar <mingo@redhat.com> (maintainer:TRACING)
>> Cc: Steven Rostedt <rostedt@goodmis.org> (maintainer:TRACING)
>> ---
>>  drivers/dma/tegra20-apb-dma.c        |  8 ++++
>>  include/trace/events/tegra_apb_dma.h | 63 
>> ++++++++++++++++++++++++++++
>>  2 files changed, 71 insertions(+)
>>  create mode 100644 include/trace/events/tegra_apb_dma.h
>> 
>> diff --git a/drivers/dma/tegra20-apb-dma.c 
>> b/drivers/dma/tegra20-apb-dma.c
>> index ce2888f67254..96095a3b7edd 100644
>> --- a/drivers/dma/tegra20-apb-dma.c
>> +++ b/drivers/dma/tegra20-apb-dma.c
>> @@ -38,6 +38,9 @@
>> 
>>  #include "dmaengine.h"
>> 
>> +#define CREATE_TRACE_POINTS
>> +#include <trace/events/tegra_apb_dma.h>
>> +
>>  #define TEGRA_APBDMA_GENERAL			0x0
>>  #define TEGRA_APBDMA_GENERAL_ENABLE		BIT(31)
>> 
>> @@ -672,6 +675,8 @@ static void tegra_dma_tasklet(unsigned long data)
>>  		dmaengine_desc_get_callback(&dma_desc->txd, &cb);
>>  		cb_count = dma_desc->cb_count;
>>  		dma_desc->cb_count = 0;
>> +		trace_tegra_dma_complete_cb(&tdc->dma_chan, cb_count,
>> +					    cb.callback);
>>  		spin_unlock_irqrestore(&tdc->lock, flags);
>>  		while (cb_count--)
>>  			dmaengine_desc_callback_invoke(&cb, NULL);
>> @@ -688,6 +693,7 @@ static irqreturn_t tegra_dma_isr(int irq, void 
>> *dev_id)
>> 
>>  	spin_lock_irqsave(&tdc->lock, flags);
>> 
>> +	trace_tegra_dma_isr(&tdc->dma_chan, irq);
>>  	status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
>>  	if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
>>  		tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status);
>> @@ -931,6 +937,8 @@ static enum dma_status tegra_dma_tx_status(struct 
>> dma_chan *dc,
>>  		dma_set_residue(txstate, residual);
>>  	}
>> 
>> +	trace_tegra_dma_tx_status(&tdc->dma_chan, cookie,
>> +				  txstate ? txstate->residue : -1);
> 
> Why just pass in txstate and put that logic into the trace event code?
> 
> See below.
> 
>>  	spin_unlock_irqrestore(&tdc->lock, flags);
>>  	return ret;
>>  }
>> diff --git a/include/trace/events/tegra_apb_dma.h 
>> b/include/trace/events/tegra_apb_dma.h
>> new file mode 100644
>> index 000000000000..80d6f0cf4c36
>> --- /dev/null
>> +++ b/include/trace/events/tegra_apb_dma.h
>> @@ -0,0 +1,63 @@
>> +#if !defined(_TRACE_TEGRA_APB_DMA_H) || 
>> defined(TRACE_HEADER_MULTI_READ)
>> +#define _TRACE_TEGRA_APM_DMA_H
>> +
>> +#include <linux/tracepoint.h>
>> +#include <linux/dmaengine.h>
>> +
>> +#undef TRACE_SYSTEM
>> +#define TRACE_SYSTEM tegra_apb_dma
>> +
>> +TRACE_EVENT(tegra_dma_tx_status,
>> +	TP_PROTO(struct dma_chan *dc, s32 cookie, u32 residue),
> 
> 	TP_PROTO(struct dma_chan *dc, s32 cookie,
> 		struct dma_tx_state *txstate),
> 
>> +	TP_ARGS(dc, cookie, residue),
> 
> 	TP_ARGS(dc, cookie, txstate),
> 
>> +	TP_STRUCT__entry(
>> +		__field(struct dma_chan *, dc)
>> +		__field(__s32,	cookie)
>> +		__field(__u32,	residue)
>> +	),
>> +	TP_fast_assign(
>> +		__entry->dc = dc;
>> +		__entry->cookie = cookie;
>> +		__entry->residue = residue;
> 
> 		__entry->residue = txstate ? txstate->residue : -1;
> 
> 
>> +	),
>> +	TP_printk("channel %s: dma cookie %d, residue %u",
>> +		  dev_name(&__entry->dc->dev->device),
> 
> The dev_name must be done in the TP_fast_assign part (use __string).
> What you have here can crash the system. That is, you saved the dc
> pointer into the ring buffer. Now that dc pointer may be freed, and
> then when you read the ring buffer, we are now dereferencing the stale
> and freed dc pointer and BOOM!
> 
> 
>> +		  __entry->cookie, __entry->residue)
>> +);
>> +
>> +TRACE_EVENT(tegra_dma_complete_cb,
>> +	    TP_PROTO(struct dma_chan *dc, int count, void *ptr),
>> +	    TP_ARGS(dc, count, ptr),
>> +	    TP_STRUCT__entry(
>> +		    __field(struct dma_chan *,	dc)
>> +		    __field(int,		count)
>> +		    __field(void *,		ptr)
>> +		    ),
>> +	    TP_fast_assign(
>> +		    __entry->dc = dc;
>> +		    __entry->count = count;
>> +		    __entry->ptr = ptr;
>> +		    ),
>> +	    TP_printk("channel %s: done %d, ptr %p",
>> +		      dev_name(&__entry->dc->dev->device),
> 
> Same here.
> 
>> +		      __entry->count, __entry->ptr)
>> +);
>> +
>> +TRACE_EVENT(tegra_dma_isr,
>> +	    TP_PROTO(struct dma_chan *dc, int irq),
>> +	    TP_ARGS(dc, irq),
>> +	    TP_STRUCT__entry(
>> +		    __field(struct dma_chan *,	dc)
>> +		    __field(int,		irq)
>> +		    ),
>> +	    TP_fast_assign(
>> +		    __entry->dc = dc;
>> +		    __entry->irq = irq;
>> +		    ),
>> +	    TP_printk("%s: irq %d\n",  dev_name(&__entry->dc->dev->device),
> 
> And here.

thank you for the review, v3 will hopefully have all these fixed.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [5/6] dma: tegra: add tracepoints to driver
@ 2018-11-01 13:54 Steven Rostedt
  0 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2018-11-01 13:54 UTC (permalink / raw)
  To: Ben Dooks
  Cc: dan.j.williams, vkoul, ldewangan, dmaengine, linux-tegra, Ingo Molnar

On Wed, 31 Oct 2018 16:03:08 +0000
Ben Dooks <ben.dooks@codethink.co.uk> wrote:


> diff --git a/include/trace/events/tegra_apb_dma.h b/include/trace/events/tegra_apb_dma.h
> new file mode 100644
> index 000000000000..1f55c2c6049d
> --- /dev/null
> +++ b/include/trace/events/tegra_apb_dma.h
> @@ -0,0 +1,61 @@
> +#if !defined(_TRACE_TEGRA_APB_DMA_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_TEGRA_APM_DMA_H
> +
> +#include <linux/tracepoint.h>
> +#include <linux/dmaengine.h>
> +
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM tegra_apb_dma
> +
> +TRACE_EVENT(tegra_dma_tx_status,
> +	TP_PROTO(struct dma_chan *dc, s32 cookie, u32 residue),
> +	TP_ARGS(dc, cookie, residue),
> +	TP_STRUCT__entry(
> +		__string(chan,	16)

Hi Ben,

Was this tested? Because I think __string(chan, 16) would fault, as the
second parameter is meant to be a pointer to the source parameter.

Otherwise, you need to add dev_name(&dc->dev->device) as the second
parameter.

If you are just using fixed string lengths then it's best not to use the
__string() type, as that's for dynamic strings (strings changing in
size for each event) and uses 8 more bytes to store the offset and
length of the string in the event.

If you take a look at the sched_waking or sched_switch trace events in
include/trace/events/sched.h you'll see that it saves the comm string
directly as a character array:

	__array(	char,	comm, 	TASK_COMM_LEN)

For you, you can use:

	__array(char, chan, 16)

> +		__field(__s32,	cookie)
> +		__field(__u32,	residue)
> +	),
> +	TP_fast_assign(
> +		__assign_str(chan, dev_name(&dc->dev->device));

Then to store the array:

		memcpy(__entry->chan, dev_name(&dc->dev->device), 16);

> +		__entry->cookie = cookie;
> +		__entry->residue = residue;
> +	),
> +	TP_printk("channel %s: dma cookie %d, residue %u",

		__entry->chan,

is all that's needed.

Same for the other references to chan.

Unless you meant to store each with a different size, then you need to
replace that "16" with the dev_name(&dc->dev->device).

-- Steve

> +		  __get_str(chan), __entry->cookie, __entry->residue)
> +);
> +
> +TRACE_EVENT(tegra_dma_complete_cb,
> +	TP_PROTO(struct dma_chan *dc, int count, void *ptr),
> +	TP_ARGS(dc, count, ptr),
> +	TP_STRUCT__entry(
> +		__string(chan,	16)
> +		__field(int,	count)
> +		__field(void *,	ptr)
> +		),
> +	TP_fast_assign(
> +		__assign_str(chan, dev_name(&dc->dev->device));
> +		__entry->count = count;
> +		__entry->ptr = ptr;
> +		),
> +	TP_printk("channel %s: done %d, ptr %p",
> +		  __get_str(chan), __entry->count, __entry->ptr)
> +);
> +
> +TRACE_EVENT(tegra_dma_isr,
> +	TP_PROTO(struct dma_chan *dc, int irq),
> +	TP_ARGS(dc, irq),
> +	TP_STRUCT__entry(
> +		__string(chan,	16)
> +		__field(int,	irq)
> +	),
> +	TP_fast_assign(
> +		__assign_str(chan, dev_name(&dc->dev->device));
> +		__entry->irq = irq;
> +	),
> +	TP_printk("%s: irq %d\n",  __get_str(chan), __entry->irq)
> +);
> +
> +#endif /*  _TRACE_TEGRADMA_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [5/6] dma: tegra: add tracepoints to driver
@ 2018-10-31 16:03 Ben Dooks
  0 siblings, 0 replies; 5+ messages in thread
From: Ben Dooks @ 2018-10-31 16:03 UTC (permalink / raw)
  To: dan.j.williams, vkoul
  Cc: ldewangan, dmaengine, linux-tegra, Ben Dooks, Ingo Molnar,
	Steven Rostedt

Add some trace-points to the driver to allow for debuging via the
trace pipe.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
Fixes since v1:
- take copy of dmachan name instead of pointer to device
Cc: Ingo Molnar <mingo@redhat.com> (maintainer:TRACING)
Cc: Steven Rostedt <rostedt@goodmis.org> (maintainer:TRACING)
---
 drivers/dma/tegra20-apb-dma.c        |  8 ++++
 include/trace/events/tegra_apb_dma.h | 61 ++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)
 create mode 100644 include/trace/events/tegra_apb_dma.h

diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 3fa3a1ac4f57..22114c9a6e98 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -38,6 +38,9 @@
 
 #include "dmaengine.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/tegra_apb_dma.h>
+
 #define TEGRA_APBDMA_GENERAL			0x0
 #define TEGRA_APBDMA_GENERAL_ENABLE		BIT(31)
 
@@ -672,6 +675,8 @@ static void tegra_dma_tasklet(unsigned long data)
 		dmaengine_desc_get_callback(&dma_desc->txd, &cb);
 		cb_count = dma_desc->cb_count;
 		dma_desc->cb_count = 0;
+		trace_tegra_dma_complete_cb(&tdc->dma_chan, cb_count,
+					    cb.callback);
 		spin_unlock_irqrestore(&tdc->lock, flags);
 		while (cb_count--)
 			dmaengine_desc_callback_invoke(&cb, NULL);
@@ -688,6 +693,7 @@ static irqreturn_t tegra_dma_isr(int irq, void *dev_id)
 
 	spin_lock_irqsave(&tdc->lock, flags);
 
+	trace_tegra_dma_isr(&tdc->dma_chan, irq);
 	status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
 	if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
 		tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status);
@@ -931,6 +937,8 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
 		dma_set_residue(txstate, residual);
 	}
 
+	trace_tegra_dma_tx_status(&tdc->dma_chan, cookie,
+				  txstate ? txstate->residue : -1);
 	spin_unlock_irqrestore(&tdc->lock, flags);
 	return ret;
 }
diff --git a/include/trace/events/tegra_apb_dma.h b/include/trace/events/tegra_apb_dma.h
new file mode 100644
index 000000000000..1f55c2c6049d
--- /dev/null
+++ b/include/trace/events/tegra_apb_dma.h
@@ -0,0 +1,61 @@
+#if !defined(_TRACE_TEGRA_APB_DMA_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_TEGRA_APM_DMA_H
+
+#include <linux/tracepoint.h>
+#include <linux/dmaengine.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM tegra_apb_dma
+
+TRACE_EVENT(tegra_dma_tx_status,
+	TP_PROTO(struct dma_chan *dc, s32 cookie, u32 residue),
+	TP_ARGS(dc, cookie, residue),
+	TP_STRUCT__entry(
+		__string(chan,	16)
+		__field(__s32,	cookie)
+		__field(__u32,	residue)
+	),
+	TP_fast_assign(
+		__assign_str(chan, dev_name(&dc->dev->device));
+		__entry->cookie = cookie;
+		__entry->residue = residue;
+	),
+	TP_printk("channel %s: dma cookie %d, residue %u",
+		  __get_str(chan), __entry->cookie, __entry->residue)
+);
+
+TRACE_EVENT(tegra_dma_complete_cb,
+	TP_PROTO(struct dma_chan *dc, int count, void *ptr),
+	TP_ARGS(dc, count, ptr),
+	TP_STRUCT__entry(
+		__string(chan,	16)
+		__field(int,	count)
+		__field(void *,	ptr)
+		),
+	TP_fast_assign(
+		__assign_str(chan, dev_name(&dc->dev->device));
+		__entry->count = count;
+		__entry->ptr = ptr;
+		),
+	TP_printk("channel %s: done %d, ptr %p",
+		  __get_str(chan), __entry->count, __entry->ptr)
+);
+
+TRACE_EVENT(tegra_dma_isr,
+	TP_PROTO(struct dma_chan *dc, int irq),
+	TP_ARGS(dc, irq),
+	TP_STRUCT__entry(
+		__string(chan,	16)
+		__field(int,	irq)
+	),
+	TP_fast_assign(
+		__assign_str(chan, dev_name(&dc->dev->device));
+		__entry->irq = irq;
+	),
+	TP_printk("%s: irq %d\n",  __get_str(chan), __entry->irq)
+);
+
+#endif /*  _TRACE_TEGRADMA_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [5/6] dma: tegra: add tracepoints to driver
@ 2018-10-12 17:01 Steven Rostedt
  0 siblings, 0 replies; 5+ messages in thread
From: Steven Rostedt @ 2018-10-12 17:01 UTC (permalink / raw)
  To: Ben Dooks
  Cc: dan.j.williams, vkoul, ldewangan, dmaengine, linux-tegra, Ingo Molnar

On Fri, 12 Oct 2018 10:44:53 +0100
Ben Dooks <ben.dooks@codethink.co.uk> wrote:

> Add some trace-points to the driver to allow for debuging via the
> trace pipe.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> Cc: Ingo Molnar <mingo@redhat.com> (maintainer:TRACING)
> Cc: Steven Rostedt <rostedt@goodmis.org> (maintainer:TRACING)
> ---
>  drivers/dma/tegra20-apb-dma.c        |  8 ++++
>  include/trace/events/tegra_apb_dma.h | 63 ++++++++++++++++++++++++++++
>  2 files changed, 71 insertions(+)
>  create mode 100644 include/trace/events/tegra_apb_dma.h
> 
> diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
> index ce2888f67254..96095a3b7edd 100644
> --- a/drivers/dma/tegra20-apb-dma.c
> +++ b/drivers/dma/tegra20-apb-dma.c
> @@ -38,6 +38,9 @@
>  
>  #include "dmaengine.h"
>  
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/tegra_apb_dma.h>
> +
>  #define TEGRA_APBDMA_GENERAL			0x0
>  #define TEGRA_APBDMA_GENERAL_ENABLE		BIT(31)
>  
> @@ -672,6 +675,8 @@ static void tegra_dma_tasklet(unsigned long data)
>  		dmaengine_desc_get_callback(&dma_desc->txd, &cb);
>  		cb_count = dma_desc->cb_count;
>  		dma_desc->cb_count = 0;
> +		trace_tegra_dma_complete_cb(&tdc->dma_chan, cb_count,
> +					    cb.callback);
>  		spin_unlock_irqrestore(&tdc->lock, flags);
>  		while (cb_count--)
>  			dmaengine_desc_callback_invoke(&cb, NULL);
> @@ -688,6 +693,7 @@ static irqreturn_t tegra_dma_isr(int irq, void *dev_id)
>  
>  	spin_lock_irqsave(&tdc->lock, flags);
>  
> +	trace_tegra_dma_isr(&tdc->dma_chan, irq);
>  	status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
>  	if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
>  		tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status);
> @@ -931,6 +937,8 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
>  		dma_set_residue(txstate, residual);
>  	}
>  
> +	trace_tegra_dma_tx_status(&tdc->dma_chan, cookie,
> +				  txstate ? txstate->residue : -1);

Why just pass in txstate and put that logic into the trace event code?

See below.

>  	spin_unlock_irqrestore(&tdc->lock, flags);
>  	return ret;
>  }
> diff --git a/include/trace/events/tegra_apb_dma.h b/include/trace/events/tegra_apb_dma.h
> new file mode 100644
> index 000000000000..80d6f0cf4c36
> --- /dev/null
> +++ b/include/trace/events/tegra_apb_dma.h
> @@ -0,0 +1,63 @@
> +#if !defined(_TRACE_TEGRA_APB_DMA_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_TEGRA_APM_DMA_H
> +
> +#include <linux/tracepoint.h>
> +#include <linux/dmaengine.h>
> +
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM tegra_apb_dma
> +
> +TRACE_EVENT(tegra_dma_tx_status,
> +	TP_PROTO(struct dma_chan *dc, s32 cookie, u32 residue),

	TP_PROTO(struct dma_chan *dc, s32 cookie,
		struct dma_tx_state *txstate),

> +	TP_ARGS(dc, cookie, residue),

	TP_ARGS(dc, cookie, txstate),

> +	TP_STRUCT__entry(
> +		__field(struct dma_chan *, dc)
> +		__field(__s32,	cookie)
> +		__field(__u32,	residue)
> +	),
> +	TP_fast_assign(
> +		__entry->dc = dc;
> +		__entry->cookie = cookie;
> +		__entry->residue = residue;

		__entry->residue = txstate ? txstate->residue : -1;


> +	),
> +	TP_printk("channel %s: dma cookie %d, residue %u",
> +		  dev_name(&__entry->dc->dev->device),

The dev_name must be done in the TP_fast_assign part (use __string).
What you have here can crash the system. That is, you saved the dc
pointer into the ring buffer. Now that dc pointer may be freed, and
then when you read the ring buffer, we are now dereferencing the stale
and freed dc pointer and BOOM!


> +		  __entry->cookie, __entry->residue)
> +);
> +
> +TRACE_EVENT(tegra_dma_complete_cb,
> +	    TP_PROTO(struct dma_chan *dc, int count, void *ptr),
> +	    TP_ARGS(dc, count, ptr),
> +	    TP_STRUCT__entry(
> +		    __field(struct dma_chan *,	dc)
> +		    __field(int,		count)
> +		    __field(void *,		ptr)
> +		    ),
> +	    TP_fast_assign(
> +		    __entry->dc = dc;
> +		    __entry->count = count;
> +		    __entry->ptr = ptr;
> +		    ),
> +	    TP_printk("channel %s: done %d, ptr %p",
> +		      dev_name(&__entry->dc->dev->device),

Same here.

> +		      __entry->count, __entry->ptr)
> +);
> +
> +TRACE_EVENT(tegra_dma_isr,
> +	    TP_PROTO(struct dma_chan *dc, int irq),
> +	    TP_ARGS(dc, irq),
> +	    TP_STRUCT__entry(
> +		    __field(struct dma_chan *,	dc)
> +		    __field(int,		irq)
> +		    ),
> +	    TP_fast_assign(
> +		    __entry->dc = dc;
> +		    __entry->irq = irq;
> +		    ),
> +	    TP_printk("%s: irq %d\n",  dev_name(&__entry->dc->dev->device),

And here.

-- Steve

> +		      __entry->irq));
> +
> +#endif /*  _TRACE_TEGRADMA_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [5/6] dma: tegra: add tracepoints to driver
@ 2018-10-12  9:44 Ben Dooks
  0 siblings, 0 replies; 5+ messages in thread
From: Ben Dooks @ 2018-10-12  9:44 UTC (permalink / raw)
  To: dan.j.williams, vkoul
  Cc: ldewangan, dmaengine, linux-tegra, Ben Dooks, Ingo Molnar,
	Steven Rostedt

Add some trace-points to the driver to allow for debuging via the
trace pipe.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
Cc: Ingo Molnar <mingo@redhat.com> (maintainer:TRACING)
Cc: Steven Rostedt <rostedt@goodmis.org> (maintainer:TRACING)
---
 drivers/dma/tegra20-apb-dma.c        |  8 ++++
 include/trace/events/tegra_apb_dma.h | 63 ++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 include/trace/events/tegra_apb_dma.h

diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index ce2888f67254..96095a3b7edd 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -38,6 +38,9 @@
 
 #include "dmaengine.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/tegra_apb_dma.h>
+
 #define TEGRA_APBDMA_GENERAL			0x0
 #define TEGRA_APBDMA_GENERAL_ENABLE		BIT(31)
 
@@ -672,6 +675,8 @@ static void tegra_dma_tasklet(unsigned long data)
 		dmaengine_desc_get_callback(&dma_desc->txd, &cb);
 		cb_count = dma_desc->cb_count;
 		dma_desc->cb_count = 0;
+		trace_tegra_dma_complete_cb(&tdc->dma_chan, cb_count,
+					    cb.callback);
 		spin_unlock_irqrestore(&tdc->lock, flags);
 		while (cb_count--)
 			dmaengine_desc_callback_invoke(&cb, NULL);
@@ -688,6 +693,7 @@ static irqreturn_t tegra_dma_isr(int irq, void *dev_id)
 
 	spin_lock_irqsave(&tdc->lock, flags);
 
+	trace_tegra_dma_isr(&tdc->dma_chan, irq);
 	status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
 	if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
 		tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status);
@@ -931,6 +937,8 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
 		dma_set_residue(txstate, residual);
 	}
 
+	trace_tegra_dma_tx_status(&tdc->dma_chan, cookie,
+				  txstate ? txstate->residue : -1);
 	spin_unlock_irqrestore(&tdc->lock, flags);
 	return ret;
 }
diff --git a/include/trace/events/tegra_apb_dma.h b/include/trace/events/tegra_apb_dma.h
new file mode 100644
index 000000000000..80d6f0cf4c36
--- /dev/null
+++ b/include/trace/events/tegra_apb_dma.h
@@ -0,0 +1,63 @@
+#if !defined(_TRACE_TEGRA_APB_DMA_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_TEGRA_APM_DMA_H
+
+#include <linux/tracepoint.h>
+#include <linux/dmaengine.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM tegra_apb_dma
+
+TRACE_EVENT(tegra_dma_tx_status,
+	TP_PROTO(struct dma_chan *dc, s32 cookie, u32 residue),
+	TP_ARGS(dc, cookie, residue),
+	TP_STRUCT__entry(
+		__field(struct dma_chan *, dc)
+		__field(__s32,	cookie)
+		__field(__u32,	residue)
+	),
+	TP_fast_assign(
+		__entry->dc = dc;
+		__entry->cookie = cookie;
+		__entry->residue = residue;
+	),
+	TP_printk("channel %s: dma cookie %d, residue %u",
+		  dev_name(&__entry->dc->dev->device),
+		  __entry->cookie, __entry->residue)
+);
+
+TRACE_EVENT(tegra_dma_complete_cb,
+	    TP_PROTO(struct dma_chan *dc, int count, void *ptr),
+	    TP_ARGS(dc, count, ptr),
+	    TP_STRUCT__entry(
+		    __field(struct dma_chan *,	dc)
+		    __field(int,		count)
+		    __field(void *,		ptr)
+		    ),
+	    TP_fast_assign(
+		    __entry->dc = dc;
+		    __entry->count = count;
+		    __entry->ptr = ptr;
+		    ),
+	    TP_printk("channel %s: done %d, ptr %p",
+		      dev_name(&__entry->dc->dev->device),
+		      __entry->count, __entry->ptr)
+);
+
+TRACE_EVENT(tegra_dma_isr,
+	    TP_PROTO(struct dma_chan *dc, int irq),
+	    TP_ARGS(dc, irq),
+	    TP_STRUCT__entry(
+		    __field(struct dma_chan *,	dc)
+		    __field(int,		irq)
+		    ),
+	    TP_fast_assign(
+		    __entry->dc = dc;
+		    __entry->irq = irq;
+		    ),
+	    TP_printk("%s: irq %d\n",  dev_name(&__entry->dc->dev->device),
+		      __entry->irq));
+
+#endif /*  _TRACE_TEGRADMA_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-11-07 10:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-07 10:02 [5/6] dma: tegra: add tracepoints to driver Ben Dooks
  -- strict thread matches above, loose matches on Subject: below --
2018-11-01 13:54 Steven Rostedt
2018-10-31 16:03 Ben Dooks
2018-10-12 17:01 Steven Rostedt
2018-10-12  9:44 Ben Dooks

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.