[Intel-wired-lan] [PATCH] ixgbevf: handle race between close and suspend on shutdown
Emil Tantilov
emil.s.tantilov at intel.com
Mon Oct 31 20:00:34 UTC 2016
When an interface is part of a namespace it is possible that
ixgbevf_close() may be called while ixgbevf_suspend() is running
which ends up in a double free WARN and/or a BUG in free_msi_irqs()
This patch introduces a new adapter->state bit that will allow us
to handle this rate atomically. The idea is that ixgbevf_close() should
not run if ixgbevf_suspend is in session.
Signed-off-by: Emil Tantilov <emil.s.tantilov at intel.com>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 +
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 5639fbe..dc4b3b4 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -446,6 +446,7 @@ enum ixbgevf_state_t {
__IXGBEVF_SERVICE_INITED,
__IXGBEVF_RESET_REQUESTED,
__IXGBEVF_QUEUE_RESET_REQUESTED,
+ __IXGBEVF_CLEAR_IRQS,
};
enum ixgbevf_boards {
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index d316f50..8ebe797 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3242,12 +3242,17 @@ int ixgbevf_close(struct net_device *netdev)
{
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+ if (test_and_set_bit(__IXGBEVF_CLEAR_IRQS, &adapter->state))
+ return 0;
+
ixgbevf_down(adapter);
ixgbevf_free_irq(adapter);
ixgbevf_free_all_tx_resources(adapter);
ixgbevf_free_all_rx_resources(adapter);
+ clear_bit(__IXGBEVF_CLEAR_IRQS, &adapter->state);
+
return 0;
}
@@ -3792,6 +3797,9 @@ static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
int retval = 0;
#endif
+ while (test_and_set_bit(__IXGBEVF_CLEAR_IRQS, &adapter->state))
+ usleep_range(1000, 2000);
+
netif_device_detach(netdev);
if (netif_running(netdev)) {
@@ -3813,6 +3821,7 @@ static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state))
pci_disable_device(pdev);
+ clear_bit(__IXGBEVF_CLEAR_IRQS, &adapter->state);
return 0;
}
More information about the Intel-wired-lan
mailing list