[PATCH 085/222] net:fec: improve safety of suspend/resume/transmit timeout paths

Russell King rmk+kernel at arm.linux.org.uk
Fri Apr 25 04:38:11 PDT 2014


We need to hold the rtnl lock while suspending, resuming or processing
the transmit timeout to ensure that netif_running() will not change
state beneath us while we bring up, take down or restart the hardware.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/net/ethernet/freescale/fec_main.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 765ea90b99ed..843721aa44bd 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -767,8 +767,10 @@ static void fec_enet_work(struct work_struct *work)
 
 	if (fep->delay_work.timeout) {
 		fep->delay_work.timeout = false;
+		rtnl_lock();
 		fec_restart(fep->netdev, fep->full_duplex);
 		netif_wake_queue(fep->netdev);
+		rtnl_unlock();
 	}
 
 	if (fep->delay_work.trig_tx) {
@@ -2333,11 +2335,14 @@ fec_suspend(struct device *dev)
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
 
+	rtnl_lock();
 	if (netif_running(ndev)) {
 		phy_stop(fep->phy_dev);
 		fec_stop(ndev);
 		netif_device_detach(ndev);
 	}
+	rtnl_unlock();
+
 	if (fep->clk_ptp)
 		clk_disable_unprepare(fep->clk_ptp);
 	if (fep->clk_enet_out)
@@ -2384,11 +2389,13 @@ fec_resume(struct device *dev)
 			goto failed_clk_ptp;
 	}
 
+	rtnl_lock();
 	if (netif_running(ndev)) {
 		fec_restart(ndev, fep->full_duplex);
 		netif_device_attach(ndev);
 		phy_start(fep->phy_dev);
 	}
+	rtnl_unlock();
 
 	return 0;
 
-- 
1.8.3.1




More information about the linux-arm-kernel mailing list