aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Persson <lars.persson@axis.com>2016-02-29 16:22:31 +0100
committerDavid S. Miller <davem@davemloft.net>2016-03-02 14:57:14 -0500
commitd4dc35f26e1017e2a632339ecae43706cbc06986 (patch)
tree30f67f7dab8e59c32d42a949521972cb5a5dae6e
parentdwc_eth_qos: fix race condition in dwceqos_start_xmit (diff)
downloadlinux-dev-d4dc35f26e1017e2a632339ecae43706cbc06986.tar.xz
linux-dev-d4dc35f26e1017e2a632339ecae43706cbc06986.zip
dwc_eth_qos: release descriptors outside netif_tx_lock
To prepare for using the CMA, we can not be in atomic context when de-allocating DMA buffers. The tx lock was needed only to protect the hw reset against the xmit handler. Now we briefly grab the tx lock while stopping the queue to make sure no thread is inside or will enter the xmit handler. Signed-off-by: Lars Persson <larper@axis.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/synopsys/dwc_eth_qos.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/ethernet/synopsys/dwc_eth_qos.c b/drivers/net/ethernet/synopsys/dwc_eth_qos.c
index 926db2d58fb5..53d48c0f41bc 100644
--- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c
+++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c
@@ -1918,15 +1918,17 @@ static int dwceqos_stop(struct net_device *ndev)
phy_stop(lp->phy_dev);
tasklet_disable(&lp->tx_bdreclaim_tasklet);
- netif_stop_queue(ndev);
napi_disable(&lp->napi);
- dwceqos_drain_dma(lp);
+ /* Stop all tx before we drain the tx dma. */
+ netif_tx_lock_bh(lp->ndev);
+ netif_stop_queue(ndev);
+ netif_tx_unlock_bh(lp->ndev);
- netif_tx_lock(lp->ndev);
+ dwceqos_drain_dma(lp);
dwceqos_reset_hw(lp);
+
dwceqos_descriptor_free(lp);
- netif_tx_unlock(lp->ndev);
return 0;
}