All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm: imx-dma: Don't change desc pointer before calling callback
@ 2016-09-12 12:50 Ian Arkver
  0 siblings, 0 replies; only message in thread
From: Ian Arkver @ 2016-09-12 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

This commit...
fcaaba6 dmaengine: imx-dma: fix callback path in tasklet
moved the test and call of the DMA completion callback function
into the tasklet exit path which is after the manipulation of ld_queue
and ld_active. This manipulation changes the desc pointer and can result
in the wrong descriptor being checked for the callback function.

One fix is to use a temporary variable to do the queue update.

Signed-off-by: Ian Jamison <ian.dev@arkver.com>
---
I found the bug and tested this patch on kernel 3.10.103 which has the
original patch backported. It was found using m2m_deinterlacer which issues
several DMAs with a callback on the last one. When the callback is called
early there is a race between the v4l2 framework returning the buffers
which invalidates the buffer pointers and the next DMA completion. This
resulted in intermittent NULL pointer dereferences. I believe the fix is
relevant to current mainline kernel as this code fragment has not changed.

  drivers/dma/imx-dma.c | 6 +++---

  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index a960608..335c2d0 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -653,10 +653,10 @@ static void imxdma_tasklet(unsigned long data)
         list_move_tail(imxdmac->ld_active.next, &imxdmac->ld_free);

         if (!list_empty(&imxdmac->ld_queue)) {
-               desc = list_first_entry(&imxdmac->ld_queue, struct 
imxdma_desc,
-                                       node);
+               struct imxdma_desc *tmpdesc = list_first_entry(
+                       &imxdmac->ld_queue, struct imxdma_desc, node);
                 list_move_tail(imxdmac->ld_queue.next, 
&imxdmac->ld_active);
-               if (imxdma_xfer_desc(desc) < 0)
+               if (imxdma_xfer_desc(tmpdesc) < 0)
                         dev_warn(imxdma->dev, "%s: channel: %d couldn't 
xfer desc\n",
                                  __func__, imxdmac->channel);
         }
--
2.9.3

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2016-09-12 12:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-12 12:50 [PATCH] arm: imx-dma: Don't change desc pointer before calling callback Ian Arkver

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.