Re: [PATCH V2 1/1] Fix a dead loop on dw shutdown

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2015-10-12 at 07:12 +0530, Viresh Kumar wrote:
> On 12-10-15, 05:27, Figo wrote:
> > We have a board it seems cannot shutdown on dw_shutdown(). It hard
> > to re-produce. It re-produce 2 times those days.
> > 
> > There is the log:
> > [   99.283522] system 00:09: shutdown start
> > [   99.287942] system 00:09: shutdown stop
> > [   99.292279] system 00:08: shutdown start
> > [   99.296700] system 00:08: shutdown stop
> > [   99.301023] pnp 00:07: shutdown start
> > [   99.305144] pnp 00:07: shutdown stop
> > [   99.309192] pnp 00:06: shutdown start
> > [   99.313323] pnp 00:06: shutdown stop
> > [   99.317357] pnp 00:05: shutdown start
> > [   99.321503] pnp 00:05: shutdown stop
> > [   99.325563] pnp 00:04: shutdown start
> > [   99.329761] pnp 00:04: shutdown stop
> > [   99.333815] pnp 00:03: shutdown start
> > [   99.337947] pnp 00:03: shutdown stop
> > [   99.342002] serial 00:02: shutdown start
> > [   99.346422] serial 00:02: shutdown stop
> > [   99.350742] system 00:01: shutdown start
> > [   99.355163] system 00:01: shutdown stop
> > [   99.359504] pnp 00:00: shutdown start
> > [   99.363632] pnp 00:00: shutdown stop
> > [   99.367700] intel_sst_acpi 808622A8:00: shutdown start
> > [   99.384530] intel_sst_acpi 808622A8:00: shutdown stop
> > [   99.390222] pxa2xx-spi 8086228E:02: shutdown start
> > [   99.395983] pxa2xx-spi 8086228E:02: shutdown stop
> > [   99.401376] pxa2xx-spi 8086228E:01: shutdown start
> > [   99.407197] pxa2xx-spi 8086228E:01: shutdown stop
> > [   99.412529] pxa2xx-spi 8086228E:00: shutdown start
> > [   99.418343] pxa2xx-spi 8086228E:00: shutdown stop
> > [   99.423652] HSU serial 8086228A:01: shutdown start
> > [   99.429078] HSU serial 8086228A:01: shutdown stop
> > [   99.434383] HSU serial 8086228A:00: shutdown start
> > [   99.439796] HSU serial 8086228A:00: shutdown stop
> > [   99.445110] dw_dmac 808622C0:00: shutdown start
> > 
> > There is potential risk of a dead loop on dmac shutdown, when the 
> > dmac
> > cannot wait the DW_CFG_DMA_EN bit on CFG register in a fault 
> > status.
> > 
> > This dead loop will let the shutdown un-finish, and the battery 
> > will drain.

This is also related to 
https://bugzilla.kernel.org/show_bug.cgi?id=101271

LPSS DMA (looks like you are using Intel hardware) has power auto
gating which can't be superseded in software. You are lucky that system
doesn't hang completely.

By the way, I think that ->shutdown() hook doesn't add a much value at
all. On one hand the users have to care about being quiescent during
shutdown, on the other there is nothing to prevent an abruption of
execution. The only thing worth to care is kexec flow.

Vinod, we have really few DMA drivers that implement ->shutdown() hook.
Do we really need it there and thus does is make sense to add to all
DMA drivers?

P.S. The patch itself was once published here 
http://www.spinics.net/lists/dmaengine/msg03964.html. So, I also wonder
how LPSS DMA power gating is working in the hardware and can we
supersede the work flow in software.

> > 
> > Signed-off-by: Figo <tianfei.zhang@xxxxxxxxx>
> > ---
> >  drivers/dma/dw/core.c |    8 ++++++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
> > index bedce03..9c5f3f5 100644
> > --- a/drivers/dma/dw/core.c
> > +++ b/drivers/dma/dw/core.c
> > @@ -1107,6 +1107,7 @@ static void dwc_issue_pending(struct dma_chan 
> > *chan)
> >  static void dw_dma_off(struct dw_dma *dw)
> >  {
> >  	int i;
> > +	int retry = 100;
> >  
> >  	dma_writel(dw, CFG, 0);
> >  
> > @@ -1115,8 +1116,11 @@ static void dw_dma_off(struct dw_dma *dw)
> >  	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
> >  	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
> >  
> > -	while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
> > -		cpu_relax();
> > +	while ((dma_readl(dw, CFG) & DW_CFG_DMA_EN) && --retry)
> > +		udelay(100);
> > +
> > +	if (retry == 0)
> > +		dev_err(&dw->dma.dev, "%s error :timeout\n", 
> > __func__);
> >  
> >  	for (i = 0; i < dw->dma.chancnt; i++)
> >  		dw->chan[i].initialized = false;
> 
> Acked-by: Viresh Kumar <viresh.kumar@xxxxxxxxxx>
> 

-- 
Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Intel Finland Oy
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux