Skip to content

Commit ba83011

Browse files
Todd Fujinakagregkh
authored andcommitted
igb: close/suspend race in netif_device_detach
[ Upstream commit 9474933caf21a4cb5147223dca1551f527aaac36 ] Similar to ixgbe, when an interface is part of a namespace it is possible that igb_close() may be called while __igb_shutdown() is running which ends up in a double free WARN and/or a BUG in free_msi_irqs(). Extend the rtnl_lock() to protect the call to netif_device_detach() and igb_clear_interrupt_scheme() in __igb_shutdown() and check for netif_device_present() to avoid calling igb_clear_interrupt_scheme() a second time in igb_close(). Also extend the rtnl lock in igb_resume() to netif_device_attach(). Signed-off-by: Todd Fujinaka <todd.fujinaka@intel.com> Acked-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 559a208 commit ba83011

1 file changed

Lines changed: 12 additions & 9 deletions

File tree

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,7 +3172,9 @@ static int __igb_close(struct net_device *netdev, bool suspending)
31723172

31733173
static int igb_close(struct net_device *netdev)
31743174
{
3175-
return __igb_close(netdev, false);
3175+
if (netif_device_present(netdev))
3176+
return __igb_close(netdev, false);
3177+
return 0;
31763178
}
31773179

31783180
/**
@@ -7325,12 +7327,14 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake,
73257327
int retval = 0;
73267328
#endif
73277329

7330+
rtnl_lock();
73287331
netif_device_detach(netdev);
73297332

73307333
if (netif_running(netdev))
73317334
__igb_close(netdev, true);
73327335

73337336
igb_clear_interrupt_scheme(adapter);
7337+
rtnl_unlock();
73347338

73357339
#ifdef CONFIG_PM
73367340
retval = pci_save_state(pdev);
@@ -7450,16 +7454,15 @@ static int igb_resume(struct device *dev)
74507454

74517455
wr32(E1000_WUS, ~0);
74527456

7453-
if (netdev->flags & IFF_UP) {
7454-
rtnl_lock();
7457+
rtnl_lock();
7458+
if (!err && netif_running(netdev))
74557459
err = __igb_open(netdev, true);
7456-
rtnl_unlock();
7457-
if (err)
7458-
return err;
7459-
}
74607460

7461-
netif_device_attach(netdev);
7462-
return 0;
7461+
if (!err)
7462+
netif_device_attach(netdev);
7463+
rtnl_unlock();
7464+
7465+
return err;
74637466
}
74647467

74657468
static int igb_runtime_idle(struct device *dev)

0 commit comments

Comments
 (0)