All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] dmaengine: nbpfaxi: fix a theoretical race
@ 2014-08-03 17:13 Guennadi Liakhovetski
       [not found] ` <Pine.LNX.4.64.1408031909420.13820-0199iw4Nj15frtckUFj5Ag@public.gmane.org>
  0 siblings, 1 reply; 2+ messages in thread
From: Guennadi Liakhovetski @ 2014-08-03 17:13 UTC (permalink / raw)
  To: dmaengine-u79uwXL29TY76Z2rM5mHXA
  Cc: Vinod Koul, Shevchenko, Andriy,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	Phil Edworthy, Arnd Bergmann

A race possibility exists if a DMA slave driver tries to free channel
resources witout waiting for all transfers to complete and without
explicitly terminating all requests. In such a case the IRQ processing
thread can race with .device_free_chan_resources(). To fix this race empty
all descriptor lists before freeing descriptor cache.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/dma/nbpfaxi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c
index 77c5a89..5b40ac8 100644
--- a/drivers/dma/nbpfaxi.c
+++ b/drivers/dma/nbpfaxi.c
@@ -1054,6 +1054,7 @@ static void nbpf_free_chan_resources(struct dma_chan *dchan)
 	dev_dbg(dchan->device->dev, "Entry %s()\n", __func__);
 
 	nbpf_chan_halt(chan);
+	nbpf_chan_idle(chan);
 	/* Clean up for if a channel is re-used for MEMCPY after slave DMA */
 	nbpf_chan_prepare_default(chan);
 
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 2/2] dmaengine: nbpfaxi: convert to tasklet
       [not found] ` <Pine.LNX.4.64.1408031909420.13820-0199iw4Nj15frtckUFj5Ag@public.gmane.org>
@ 2014-08-03 17:13   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 2+ messages in thread
From: Guennadi Liakhovetski @ 2014-08-03 17:13 UTC (permalink / raw)
  To: dmaengine-u79uwXL29TY76Z2rM5mHXA
  Cc: Vinod Koul, Shevchenko, Andriy,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Grant Likely, Rob Herring,
	Phil Edworthy, Arnd Bergmann

It is common among dmaengine drivers to use a tasklet for bottom half
interrupt processing. Convert nbpfaxi to do the same.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski-Mmb7MZpHnFY@public.gmane.org>
---
 drivers/dma/nbpfaxi.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c
index 5b40ac8..cea6a37 100644
--- a/drivers/dma/nbpfaxi.c
+++ b/drivers/dma/nbpfaxi.c
@@ -197,6 +197,7 @@ struct nbpf_desc_page {
  */
 struct nbpf_channel {
 	struct dma_chan dma_chan;
+	struct tasklet_struct tasklet;
 	void __iomem *base;
 	struct nbpf_device *nbpf;
 	char name[16];
@@ -1111,9 +1112,9 @@ static struct dma_chan *nbpf_of_xlate(struct of_phandle_args *dma_spec,
 	return dchan;
 }
 
-static irqreturn_t nbpf_chan_irqt(int irq, void *dev)
+static void nbpf_chan_tasklet(unsigned long data)
 {
-	struct nbpf_channel *chan = dev;
+	struct nbpf_channel *chan = (struct nbpf_channel *)data;
 	struct nbpf_desc *desc, *tmp;
 	dma_async_tx_callback callback;
 	void *param;
@@ -1176,8 +1177,6 @@ static irqreturn_t nbpf_chan_irqt(int irq, void *dev)
 		if (must_put)
 			nbpf_desc_put(desc);
 	}
-
-	return IRQ_HANDLED;
 }
 
 static irqreturn_t nbpf_chan_irq(int irq, void *dev)
@@ -1186,6 +1185,7 @@ static irqreturn_t nbpf_chan_irq(int irq, void *dev)
 	bool done = nbpf_status_get(chan);
 	struct nbpf_desc *desc;
 	irqreturn_t ret;
+	bool bh = false;
 
 	if (!done)
 		return IRQ_NONE;
@@ -1200,7 +1200,8 @@ static irqreturn_t nbpf_chan_irq(int irq, void *dev)
 		ret = IRQ_NONE;
 		goto unlock;
 	} else {
-		ret = IRQ_WAKE_THREAD;
+		ret = IRQ_HANDLED;
+		bh = true;
 	}
 
 	list_move_tail(&desc->node, &chan->done);
@@ -1216,6 +1217,9 @@ static irqreturn_t nbpf_chan_irq(int irq, void *dev)
 unlock:
 	spin_unlock(&chan->lock);
 
+	if (bh)
+		tasklet_schedule(&chan->tasklet);
+
 	return ret;
 }
 
@@ -1258,8 +1262,9 @@ static int nbpf_chan_probe(struct nbpf_device *nbpf, int n)
 
 	snprintf(chan->name, sizeof(chan->name), "nbpf %d", n);
 
-	ret = devm_request_threaded_irq(dma_dev->dev, chan->irq,
-			nbpf_chan_irq, nbpf_chan_irqt, IRQF_SHARED,
+	tasklet_init(&chan->tasklet, nbpf_chan_tasklet, (unsigned long)chan);
+	ret = devm_request_irq(dma_dev->dev, chan->irq,
+			nbpf_chan_irq, IRQF_SHARED,
 			chan->name, chan);
 	if (ret < 0)
 		return ret;
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2014-08-03 17:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-03 17:13 [PATCH 1/2] dmaengine: nbpfaxi: fix a theoretical race Guennadi Liakhovetski
     [not found] ` <Pine.LNX.4.64.1408031909420.13820-0199iw4Nj15frtckUFj5Ag@public.gmane.org>
2014-08-03 17:13   ` [PATCH 2/2] dmaengine: nbpfaxi: convert to tasklet Guennadi Liakhovetski

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.