[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <c4e0980b1d5eb5ba48e1cdebe565d3d6bd3a4dc0.1490375512.git.jpinto@synopsys.com>
Date: Fri, 24 Mar 2017 17:16:44 +0000
From: Joao Pinto <Joao.Pinto@...opsys.com>
To: davem@...emloft.net
Cc: peppe.cavallaro@...com, alexandre.torgue@...com,
clabbe.montjoie@...il.com, thierry.reding@...il.com,
sergei.shtylyov@...entembedded.com, f.fainelli@...il.com,
niklas.cassel@...s.com, netdev@...r.kernel.org,
Joao Pinto <Joao.Pinto@...opsys.com>
Subject: [PATCH net-next 1/2] net: stmmac: fix netdev release
This patch fixes the kernel crash problem that happens when the driver
exits. The dma resouces must be freed after netdev resouces get freed and
in driver removed, multiple napi's should be deleted before removing
netdev resouces or it will hang.
Signed-off-by: Joao Pinto <jpinto@...opsys.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 4b418d2..3827952 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2659,9 +2659,6 @@ static int stmmac_release(struct net_device *dev)
/* Stop TX/RX DMA and clear the descriptors */
stmmac_stop_all_dma(priv);
- /* Release and free the Rx/Tx resources */
- free_dma_desc_resources(priv);
-
/* Disable the MAC Rx/Tx */
stmmac_set_mac(priv->ioaddr, false);
@@ -4080,7 +4077,7 @@ int stmmac_dvr_probe(struct device *device,
/* Init MAC and get the capabilities */
ret = stmmac_hw_init(priv);
if (ret)
- goto error_hw_init;
+ return ret;
/* Configure real RX and TX queues */
ndev->real_num_rx_queues = priv->plat->rx_queues_to_use;
@@ -4207,9 +4204,8 @@ int stmmac_dvr_probe(struct device *device,
netif_napi_del(&rx_q->napi);
}
init_dma_error:
- free_dma_desc_resources(priv);
-error_hw_init:
free_netdev(ndev);
+ free_dma_desc_resources(priv);
return ret;
}
@@ -4225,6 +4221,7 @@ int stmmac_dvr_remove(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
+ u32 queue = 0;
netdev_info(priv->dev, "%s: removing driver", __func__);
@@ -4241,7 +4238,15 @@ int stmmac_dvr_remove(struct device *dev)
priv->hw->pcs != STMMAC_PCS_TBI &&
priv->hw->pcs != STMMAC_PCS_RTBI)
stmmac_mdio_unregister(ndev);
+
+ for (queue = 0; queue < priv->plat->rx_queues_to_use; queue++) {
+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+
+ netif_napi_del(&rx_q->napi);
+ }
+
free_netdev(ndev);
+ free_dma_desc_resources(priv);
return 0;
}
--
2.9.3
Powered by blists - more mailing lists