All of lore.kernel.org
 help / color / mirror / Atom feed
From: vinod.koul@intel.com (Vinod Koul)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: dma: imx: Fix deadlock bug
Date: Wed, 12 Jun 2013 08:33:22 +0530	[thread overview]
Message-ID: <20130612030321.GA4107@intel.com> (raw)
In-Reply-To: <20130608211557.GK18614@n2100.arm.linux.org.uk>

On Sat, Jun 08, 2013 at 10:15:57PM +0100, Russell King - ARM Linux wrote:
> On Sun, Jun 09, 2013 at 12:56:28AM +0400, Alexander Shiyan wrote:
> > @@ -625,8 +613,9 @@ static void imxdma_tasklet(unsigned long data)
> >  	struct imxdma_channel *imxdmac = (void *)data;
> >  	struct imxdma_engine *imxdma = imxdmac->imxdma;
> >  	struct imxdma_desc *desc;
> > +	unsigned long flags;
> >  
> > -	spin_lock(&imxdma->lock);
> > +	spin_lock_irqsave(&imxdma->lock, flags);
> >  
> >  	if (list_empty(&imxdmac->ld_active)) {
> >  		/* Someone might have called terminate all */
> > @@ -663,7 +652,7 @@ static void imxdma_tasklet(unsigned long data)
> >  				 __func__, imxdmac->channel);
> >  	}
> >  out:
> > -	spin_unlock(&imxdma->lock);
> > +	spin_unlock_irqrestore(&imxdma->lock, flags);
> 
> So, I just peeked at this driver.  Who is reviewing DMA engine drivers
> and why aren't they reviewing stuff properly.
mea culpa, yes its documeneted well. Let me fix it up...

> 
> static void imxdma_tasklet(unsigned long data)
> {
> ...
>         spin_lock(&imxdma->lock);
> ...
>         if (desc->desc.callback)
>                 desc->desc.callback(desc->desc.callback_param);
> ...
> out:
>         spin_unlock(&imxdma->lock);
> }
> 
> This stuff is well known and even documented:
> 
>         For slave DMA, the subsequent transaction may not be available
>         for submission prior to callback function being invoked, so
>         slave DMA callbacks are permitted to prepare and submit a new
>         transaction.
> 
>         For cyclic DMA, a callback function may wish to terminate the
>         DMA via dmaengine_terminate_all().
> 
>         Therefore, it is important that DMA engine drivers drop any
>         locks before calling the callback function which may cause a
>         deadlock.
> 
>         Note that callbacks will always be invoked from the DMA
>         engines tasklet, never from interrupt context.
> 
> Note the 3rd paragraph - and note that the IMX driver violates this
> by holding that spinlock.  Changing that spinlock to be an irq-saving
> type just makes the problem worse.
> 
> What's more is it takes this same lock in the submit and issue_pending
> functions - so this is potential deadlock territory by the mere fact
> that a callback function _can_ invoke these two functions.
> 
> It also makes use of __memzero.  Don't.  Use memset().
> 
> Doesn't check the return value of clk_prepare_enable().
> 
> Mixes up accessors and direct accesses:
>                 imxdmac->sg_list[i].dma_address = dma_addr;
>                 sg_dma_len(&imxdmac->sg_list[i]) = period_len;
> The first should be accessed via sg_dma_address().
> 
> Reimplements much of virt-dma.c/.h - maybe it should use this support
> instead?  As an added benefit you'll be able to start the next queued
> request without the tasklet and get better throughput as a result -
> and process all completed transfers upon tasklet invocation.

--
~Vinod

-- 

  reply	other threads:[~2013-06-12  3:03 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-08 20:56 [PATCH] ARM: dma: imx: Fix deadlock bug Alexander Shiyan
2013-06-08 21:07 ` Fabio Estevam
2013-06-08 21:19   ` Russell King - ARM Linux
2013-06-08 21:15 ` Russell King - ARM Linux
2013-06-12  3:03   ` Vinod Koul [this message]
2013-07-15  8:13     ` Christoph Fritz
2013-07-15 10:01       ` Vinod Koul
2013-07-15 16:09         ` Christoph Fritz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130612030321.GA4107@intel.com \
    --to=vinod.koul@intel.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.