linux-arm-kernel.lists.infradead.org archive mirror
 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 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).