linux-samsung-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers
@ 2016-12-16 10:39 Marek Szyprowski
  2016-12-23  2:33 ` Krzysztof Kozlowski
  2017-01-03  3:49 ` Vinod Koul
  0 siblings, 2 replies; 5+ messages in thread
From: Marek Szyprowski @ 2016-12-16 10:39 UTC (permalink / raw)
  To: linux-samsung-soc, dmaengine, linux-arm-kernel
  Cc: Marek Szyprowski, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
	Vinod Koul

PL330 DMA engine driver is leaking a runtime reference after any terminated
DMA transactions. This patch fixes this issue by tracking runtime PM state
of the device and making additional call to pm_runtime_put() in terminate_all
callback if needed.

Fixes: ae43b3289186 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/dma/pl330.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 030fe05ed43b..9f3dbc8c63d2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -448,6 +448,9 @@ struct dma_pl330_chan {
 
 	/* for cyclic capability */
 	bool cyclic;
+
+	/* for runtime pm tracking */
+	bool active;
 };
 
 struct pl330_dmac {
@@ -2031,6 +2034,7 @@ static void pl330_tasklet(unsigned long data)
 		_stop(pch->thread);
 		spin_unlock(&pch->thread->dmac->lock);
 		power_down = true;
+		pch->active = false;
 	} else {
 		/* Make sure the PL330 Channel thread is active */
 		spin_lock(&pch->thread->dmac->lock);
@@ -2050,6 +2054,7 @@ static void pl330_tasklet(unsigned long data)
 			desc->status = PREP;
 			list_move_tail(&desc->node, &pch->work_list);
 			if (power_down) {
+				pch->active = true;
 				spin_lock(&pch->thread->dmac->lock);
 				_start(pch->thread);
 				spin_unlock(&pch->thread->dmac->lock);
@@ -2164,6 +2169,7 @@ static int pl330_terminate_all(struct dma_chan *chan)
 	unsigned long flags;
 	struct pl330_dmac *pl330 = pch->dmac;
 	LIST_HEAD(list);
+	bool power_down = false;
 
 	pm_runtime_get_sync(pl330->ddma.dev);
 	spin_lock_irqsave(&pch->lock, flags);
@@ -2174,6 +2180,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
 	pch->thread->req[0].desc = NULL;
 	pch->thread->req[1].desc = NULL;
 	pch->thread->req_running = -1;
+	power_down = pch->active;
+	pch->active = false;
 
 	/* Mark all desc done */
 	list_for_each_entry(desc, &pch->submitted_list, node) {
@@ -2191,6 +2199,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
 	list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
 	spin_unlock_irqrestore(&pch->lock, flags);
 	pm_runtime_mark_last_busy(pl330->ddma.dev);
+	if (power_down)
+		pm_runtime_put_autosuspend(pl330->ddma.dev);
 	pm_runtime_put_autosuspend(pl330->ddma.dev);
 
 	return 0;
@@ -2350,6 +2360,7 @@ static void pl330_issue_pending(struct dma_chan *chan)
 		 * updated on work_list emptiness status.
 		 */
 		WARN_ON(list_empty(&pch->submitted_list));
+		pch->active = true;
 		pm_runtime_get_sync(pch->dmac->ddma.dev);
 	}
 	list_splice_tail_init(&pch->submitted_list, &pch->work_list);
-- 
1.9.1

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

* Re: [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers
  2016-12-16 10:39 [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers Marek Szyprowski
@ 2016-12-23  2:33 ` Krzysztof Kozlowski
  2016-12-23  9:52   ` Marek Szyprowski
  2017-01-03  3:49 ` Vinod Koul
  1 sibling, 1 reply; 5+ messages in thread
From: Krzysztof Kozlowski @ 2016-12-23  2:33 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-samsung-soc, dmaengine, linux-arm-kernel,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz, Vinod Koul

On Fri, Dec 16, 2016 at 11:39:11AM +0100, Marek Szyprowski wrote:
> PL330 DMA engine driver is leaking a runtime reference after any terminated
> DMA transactions. This patch fixes this issue by tracking runtime PM state
> of the device and making additional call to pm_runtime_put() in terminate_all
> callback if needed.
> 
> Fixes: ae43b3289186 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12")
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/dma/pl330.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 030fe05ed43b..9f3dbc8c63d2 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -448,6 +448,9 @@ struct dma_pl330_chan {
>  
>  	/* for cyclic capability */
>  	bool cyclic;
> +
> +	/* for runtime pm tracking */
> +	bool active;
>  };
>  
>  struct pl330_dmac {
> @@ -2031,6 +2034,7 @@ static void pl330_tasklet(unsigned long data)
>  		_stop(pch->thread);
>  		spin_unlock(&pch->thread->dmac->lock);
>  		power_down = true;
> +		pch->active = false;
>  	} else {
>  		/* Make sure the PL330 Channel thread is active */
>  		spin_lock(&pch->thread->dmac->lock);
> @@ -2050,6 +2054,7 @@ static void pl330_tasklet(unsigned long data)
>  			desc->status = PREP;
>  			list_move_tail(&desc->node, &pch->work_list);
>  			if (power_down) {
> +				pch->active = true;

It's been a while since I was playign with the driver so I don't
remember everything... but I can't get the logic behind this.

The device is marked as inactive and scheduled to power down. But you
mark chanel as active.

Maybe it is correct but for me it is unreadable.

I understand that you wanted to mark the device as active at some point,
in case transfer was terminated?

Best regards,
Krzysztof

>  				spin_lock(&pch->thread->dmac->lock);
>  				_start(pch->thread);
>  				spin_unlock(&pch->thread->dmac->lock);
> @@ -2164,6 +2169,7 @@ static int pl330_terminate_all(struct dma_chan *chan)
>  	unsigned long flags;
>  	struct pl330_dmac *pl330 = pch->dmac;
>  	LIST_HEAD(list);
> +	bool power_down = false;
>  
>  	pm_runtime_get_sync(pl330->ddma.dev);
>  	spin_lock_irqsave(&pch->lock, flags);
> @@ -2174,6 +2180,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
>  	pch->thread->req[0].desc = NULL;
>  	pch->thread->req[1].desc = NULL;
>  	pch->thread->req_running = -1;
> +	power_down = pch->active;
> +	pch->active = false;
>  
>  	/* Mark all desc done */
>  	list_for_each_entry(desc, &pch->submitted_list, node) {
> @@ -2191,6 +2199,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
>  	list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
>  	spin_unlock_irqrestore(&pch->lock, flags);
>  	pm_runtime_mark_last_busy(pl330->ddma.dev);
> +	if (power_down)
> +		pm_runtime_put_autosuspend(pl330->ddma.dev);
>  	pm_runtime_put_autosuspend(pl330->ddma.dev);
>  
>  	return 0;
> @@ -2350,6 +2360,7 @@ static void pl330_issue_pending(struct dma_chan *chan)
>  		 * updated on work_list emptiness status.
>  		 */
>  		WARN_ON(list_empty(&pch->submitted_list));
> +		pch->active = true;
>  		pm_runtime_get_sync(pch->dmac->ddma.dev);
>  	}
>  	list_splice_tail_init(&pch->submitted_list, &pch->work_list);
> -- 
> 1.9.1
> 

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

* Re: [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers
  2016-12-23  2:33 ` Krzysztof Kozlowski
@ 2016-12-23  9:52   ` Marek Szyprowski
  2016-12-24 11:13     ` Krzysztof Kozlowski
  0 siblings, 1 reply; 5+ messages in thread
From: Marek Szyprowski @ 2016-12-23  9:52 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, dmaengine, linux-arm-kernel,
	Bartlomiej Zolnierkiewicz, Vinod Koul

Hi Krzysztof,


On 2016-12-23 03:33, Krzysztof Kozlowski wrote:
> On Fri, Dec 16, 2016 at 11:39:11AM +0100, Marek Szyprowski wrote:
>> PL330 DMA engine driver is leaking a runtime reference after any terminated
>> DMA transactions. This patch fixes this issue by tracking runtime PM state
>> of the device and making additional call to pm_runtime_put() in terminate_all
>> callback if needed.
>>
>> Fixes: ae43b3289186 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12")
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>   drivers/dma/pl330.c | 11 +++++++++++
>>   1 file changed, 11 insertions(+)
>>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index 030fe05ed43b..9f3dbc8c63d2 100644
>> --- a/drivers/dma/pl330.c
>> +++ b/drivers/dma/pl330.c
>> @@ -448,6 +448,9 @@ struct dma_pl330_chan {
>>   
>>   	/* for cyclic capability */
>>   	bool cyclic;
>> +
>> +	/* for runtime pm tracking */
>> +	bool active;
>>   };
>>   
>>   struct pl330_dmac {
>> @@ -2031,6 +2034,7 @@ static void pl330_tasklet(unsigned long data)
>>   		_stop(pch->thread);
>>   		spin_unlock(&pch->thread->dmac->lock);
>>   		power_down = true;
>> +		pch->active = false;
>>   	} else {
>>   		/* Make sure the PL330 Channel thread is active */
>>   		spin_lock(&pch->thread->dmac->lock);
>> @@ -2050,6 +2054,7 @@ static void pl330_tasklet(unsigned long data)
>>   			desc->status = PREP;
>>   			list_move_tail(&desc->node, &pch->work_list);
>>   			if (power_down) {
>> +				pch->active = true;
> It's been a while since I was playign with the driver so I don't
> remember everything... but I can't get the logic behind this.
>
> The device is marked as inactive and scheduled to power down. But you
> mark chanel as active.

Please look 3 lines further. The channel is started again (because this
is cyclic request), so setting active to true is justified. Even power_down
is then set to false.

> Maybe it is correct but for me it is unreadable.
>
> I understand that you wanted to mark the device as active at some point,
> in case transfer was terminated?

Frankly, I have no idea how to explain it more clear. Cyclic transfers are
automatically restarted, so the above logic simply keeps pch->active in sync
with hardware operations.

>
> Best regards,
> Krzysztof
>
>>   				spin_lock(&pch->thread->dmac->lock);
>>   				_start(pch->thread);
>>   				spin_unlock(&pch->thread->dmac->lock);
>> @@ -2164,6 +2169,7 @@ static int pl330_terminate_all(struct dma_chan *chan)
>>   	unsigned long flags;
>>   	struct pl330_dmac *pl330 = pch->dmac;
>>   	LIST_HEAD(list);
>> +	bool power_down = false;
>>   
>>   	pm_runtime_get_sync(pl330->ddma.dev);
>>   	spin_lock_irqsave(&pch->lock, flags);
>> @@ -2174,6 +2180,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
>>   	pch->thread->req[0].desc = NULL;
>>   	pch->thread->req[1].desc = NULL;
>>   	pch->thread->req_running = -1;
>> +	power_down = pch->active;
>> +	pch->active = false;
>>   
>>   	/* Mark all desc done */
>>   	list_for_each_entry(desc, &pch->submitted_list, node) {
>> @@ -2191,6 +2199,8 @@ static int pl330_terminate_all(struct dma_chan *chan)
>>   	list_splice_tail_init(&pch->completed_list, &pl330->desc_pool);
>>   	spin_unlock_irqrestore(&pch->lock, flags);
>>   	pm_runtime_mark_last_busy(pl330->ddma.dev);
>> +	if (power_down)
>> +		pm_runtime_put_autosuspend(pl330->ddma.dev);
>>   	pm_runtime_put_autosuspend(pl330->ddma.dev);
>>   
>>   	return 0;
>> @@ -2350,6 +2360,7 @@ static void pl330_issue_pending(struct dma_chan *chan)
>>   		 * updated on work_list emptiness status.
>>   		 */
>>   		WARN_ON(list_empty(&pch->submitted_list));
>> +		pch->active = true;
>>   		pm_runtime_get_sync(pch->dmac->ddma.dev);
>>   	}
>>   	list_splice_tail_init(&pch->submitted_list, &pch->work_list);
>> -- 
>> 1.9.1
>>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

* Re: [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers
  2016-12-23  9:52   ` Marek Szyprowski
@ 2016-12-24 11:13     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 5+ messages in thread
From: Krzysztof Kozlowski @ 2016-12-24 11:13 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Krzysztof Kozlowski, linux-samsung-soc, dmaengine,
	linux-arm-kernel, Bartlomiej Zolnierkiewicz, Vinod Koul

On Fri, Dec 23, 2016 at 10:52:28AM +0100, Marek Szyprowski wrote:
> Hi Krzysztof,
> 
> 
> On 2016-12-23 03:33, Krzysztof Kozlowski wrote:
> >On Fri, Dec 16, 2016 at 11:39:11AM +0100, Marek Szyprowski wrote:
> >>PL330 DMA engine driver is leaking a runtime reference after any terminated
> >>DMA transactions. This patch fixes this issue by tracking runtime PM state
> >>of the device and making additional call to pm_runtime_put() in terminate_all
> >>callback if needed.
> >>
> >>Fixes: ae43b3289186 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12")
> >>Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> >>---
> >>  drivers/dma/pl330.c | 11 +++++++++++
> >>  1 file changed, 11 insertions(+)
> >>
> >>diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> >>index 030fe05ed43b..9f3dbc8c63d2 100644
> >>--- a/drivers/dma/pl330.c
> >>+++ b/drivers/dma/pl330.c
> >>@@ -448,6 +448,9 @@ struct dma_pl330_chan {
> >>  	/* for cyclic capability */
> >>  	bool cyclic;
> >>+
> >>+	/* for runtime pm tracking */
> >>+	bool active;
> >>  };
> >>  struct pl330_dmac {
> >>@@ -2031,6 +2034,7 @@ static void pl330_tasklet(unsigned long data)
> >>  		_stop(pch->thread);
> >>  		spin_unlock(&pch->thread->dmac->lock);
> >>  		power_down = true;
> >>+		pch->active = false;
> >>  	} else {
> >>  		/* Make sure the PL330 Channel thread is active */
> >>  		spin_lock(&pch->thread->dmac->lock);
> >>@@ -2050,6 +2054,7 @@ static void pl330_tasklet(unsigned long data)
> >>  			desc->status = PREP;
> >>  			list_move_tail(&desc->node, &pch->work_list);
> >>  			if (power_down) {
> >>+				pch->active = true;
> >It's been a while since I was playign with the driver so I don't
> >remember everything... but I can't get the logic behind this.
> >
> >The device is marked as inactive and scheduled to power down. But you
> >mark chanel as active.
> 
> Please look 3 lines further. The channel is started again (because this
> is cyclic request), so setting active to true is justified. Even power_down
> is then set to false.

Ahhh, damn the missing context. I looked at full source and it makes
sense now.

Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

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

* Re: [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers
  2016-12-16 10:39 [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers Marek Szyprowski
  2016-12-23  2:33 ` Krzysztof Kozlowski
@ 2017-01-03  3:49 ` Vinod Koul
  1 sibling, 0 replies; 5+ messages in thread
From: Vinod Koul @ 2017-01-03  3:49 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-samsung-soc, dmaengine, linux-arm-kernel,
	Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz

On Fri, Dec 16, 2016 at 11:39:11AM +0100, Marek Szyprowski wrote:
> PL330 DMA engine driver is leaking a runtime reference after any terminated
> DMA transactions. This patch fixes this issue by tracking runtime PM state
> of the device and making additional call to pm_runtime_put() in terminate_all
> callback if needed.

Applied now

-- 
~Vinod

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

end of thread, other threads:[~2017-01-03  3:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-16 10:39 [PATCH] dmaengine: pl330: Fix runtime PM support for terminated transfers Marek Szyprowski
2016-12-23  2:33 ` Krzysztof Kozlowski
2016-12-23  9:52   ` Marek Szyprowski
2016-12-24 11:13     ` Krzysztof Kozlowski
2017-01-03  3:49 ` Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).