From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tony Lindgren Subject: Re: [PATCH] dmaengine: cppi41: Fix oops in cppi41_runtime_resume Date: Thu, 12 Jan 2017 16:03:15 -0800 Message-ID: <20170113000314.GU2630@atomide.com> References: <20170112213016.19367-1-tony@atomide.com> <927792da-2e90-b2ae-1206-8fcb504d7551@ti.com> <20170112221933.GM2630@atomide.com> <1c8967b7-d59b-e53d-feeb-80c71464fb94@ti.com> <20170112230456.GS2630@atomide.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline In-Reply-To: Sender: linux-usb-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Grygorii Strashko Cc: Dan Williams , Vinod Koul , Bin Liu , Daniel Mack , Felipe Balbi , George Cherian , Johan Hovold , Peter Ujfalusi , Sekhar Nori , Sebastian Andrzej Siewior , dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Andy Shevchenko , Kevin Hilman , Patrick Titiano , Sergei Shtylyov List-Id: linux-omap@vger.kernel.org * Grygorii Strashko [170112 15:43]: > @@ -457,38 +449,36 @@ static void push_desc_queue(struct cppi41_channel *c) > cppi_writel(reg, cdd->qmgr_mem + QMGR_QUEUE_D(c->q_num)); > } > > -static void pending_desc(struct cppi41_channel *c) > +static void cppi41_dma_issue_pending(struct dma_chan *chan) > { > + struct cppi41_channel *c = to_cpp41_chan(chan); > struct cppi41_dd *cdd = c->cdd; > + int error; > + struct cppi41_channel *_c; > unsigned long flags; > > spin_lock_irqsave(&cdd->lock, flags); > list_add_tail(&c->node, &cdd->pending); > - spin_unlock_irqrestore(&cdd->lock, flags); > -} > - > -static void cppi41_dma_issue_pending(struct dma_chan *chan) > -{ > - struct cppi41_channel *c = to_cpp41_chan(chan); > - struct cppi41_dd *cdd = c->cdd; > - int error; > > error = pm_runtime_get(cdd->ddev.dev); > - if ((error != -EINPROGRESS) && error < 0) { > + if (error < 0) { > pm_runtime_put_noidle(cdd->ddev.dev); > dev_err(cdd->ddev.dev, "Failed to pm_runtime_get: %i\n", > error); > - > + spin_unlock_irqrestore(&cdd->lock, flags); > return; > } > > - if (likely(pm_runtime_active(cdd->ddev.dev))) > - push_desc_queue(c); > - else > - pending_desc(c); > + if (!cdd->is_suspended) { > + list_for_each_entry_safe(c, _c, &cdd->pending, node) { > + push_desc_queue(c); > + list_del(&c->node); > + }; > + } > > pm_runtime_mark_last_busy(cdd->ddev.dev); > pm_runtime_put_autosuspend(cdd->ddev.dev); > + spin_lock_irqsave(&cdd->lock, flags); > } So always add to the queue no matter, then always flush the queue directly if active? Yeah that might work :) Don't we need spinlock in the list_for_each_entry_safe() to prevent it racing with runtime_resume() though? Tony -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html