Commit fccd5bad authored by Grygorii Strashko's avatar Grygorii Strashko Committed by David S. Miller
Browse files

net: ethernet: ti: cpdma: fix lockup in cpdma_ctlr_destroy()



Fix deadlock in cpdma_ctlr_destroy() which is triggered now on
cpsw module removal:
 cpsw_remove()
 - cpdma_ctlr_destroy()
   - spin_lock_irqsave(&ctlr->lock, flags)
   - cpdma_ctlr_stop()
     - spin_lock_irqsave(&ctlr->lock, flags);
   - cpdma_chan_destroy()
     - spin_lock_irqsave(&ctlr->lock, flags);

The issue has not been observed before because CPDMA channels have
been destroyed manually by CPSW until commit d941ebe8 ("net:
ethernet: ti: cpsw: use destroy ctlr to destroy channels") was merged.

Signed-off-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: default avatarMugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c882219a
Loading
Loading
Loading
Loading
+0 −3
Original line number Original line Diff line number Diff line
@@ -357,13 +357,11 @@ EXPORT_SYMBOL_GPL(cpdma_ctlr_stop);


int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
{
{
	unsigned long flags;
	int ret = 0, i;
	int ret = 0, i;


	if (!ctlr)
	if (!ctlr)
		return -EINVAL;
		return -EINVAL;


	spin_lock_irqsave(&ctlr->lock, flags);
	if (ctlr->state != CPDMA_STATE_IDLE)
	if (ctlr->state != CPDMA_STATE_IDLE)
		cpdma_ctlr_stop(ctlr);
		cpdma_ctlr_stop(ctlr);


@@ -371,7 +369,6 @@ int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr)
		cpdma_chan_destroy(ctlr->channels[i]);
		cpdma_chan_destroy(ctlr->channels[i]);


	cpdma_desc_pool_destroy(ctlr->pool);
	cpdma_desc_pool_destroy(ctlr->pool);
	spin_unlock_irqrestore(&ctlr->lock, flags);
	return ret;
	return ret;
}
}
EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);
EXPORT_SYMBOL_GPL(cpdma_ctlr_destroy);