aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rustad <mark.d.rustad@intel.com>2014-03-11 20:38:35 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-03-31 18:48:03 -0400
commit41c62843eb6a0ea3e2f1e06ca3ec7b2f64452f7b (patch)
treede994b24163c5e42a9e75fd8d750eb090856e5e5
parent75009b3a88cd8f56315eb4ced296ee2f060cf946 (diff)
ixgbe: Fix rcu warnings induced by LER
Resolve some rcu warnings produced when LER actions take place. This appears to be due to not holding the rtnl lock when calling ixgbe_down, so hold the lock. Also avoid disabling the device when it is already disabled. This check is necessary because the callback can be called more than once in some cases. Signed-off-by: Mark Rustad <mark.d.rustad@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c23
2 files changed, 19 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 26d27aae9793..55c53a1cbb62 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -808,6 +808,7 @@ enum ixgbe_state_t {
808 __IXGBE_TESTING, 808 __IXGBE_TESTING,
809 __IXGBE_RESETTING, 809 __IXGBE_RESETTING,
810 __IXGBE_DOWN, 810 __IXGBE_DOWN,
811 __IXGBE_DISABLED,
811 __IXGBE_REMOVING, 812 __IXGBE_REMOVING,
812 __IXGBE_SERVICE_SCHED, 813 __IXGBE_SERVICE_SCHED,
813 __IXGBE_IN_SFP_INIT, 814 __IXGBE_IN_SFP_INIT,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index c4b930c0ce7f..8436c651b735 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5566,6 +5566,8 @@ static int ixgbe_resume(struct pci_dev *pdev)
5566 e_dev_err("Cannot enable PCI device from suspend\n"); 5566 e_dev_err("Cannot enable PCI device from suspend\n");
5567 return err; 5567 return err;
5568 } 5568 }
5569 smp_mb__before_clear_bit();
5570 clear_bit(__IXGBE_DISABLED, &adapter->state);
5569 pci_set_master(pdev); 5571 pci_set_master(pdev);
5570 5572
5571 pci_wake_from_d3(pdev, false); 5573 pci_wake_from_d3(pdev, false);
@@ -5663,7 +5665,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
5663 5665
5664 ixgbe_release_hw_control(adapter); 5666 ixgbe_release_hw_control(adapter);
5665 5667
5666 pci_disable_device(pdev); 5668 if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
5669 pci_disable_device(pdev);
5667 5670
5668 return 0; 5671 return 0;
5669} 5672}
@@ -8313,7 +8316,8 @@ err_alloc_etherdev:
8313 pci_select_bars(pdev, IORESOURCE_MEM)); 8316 pci_select_bars(pdev, IORESOURCE_MEM));
8314err_pci_reg: 8317err_pci_reg:
8315err_dma: 8318err_dma:
8316 pci_disable_device(pdev); 8319 if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
8320 pci_disable_device(pdev);
8317 return err; 8321 return err;
8318} 8322}
8319 8323
@@ -8382,7 +8386,8 @@ static void ixgbe_remove(struct pci_dev *pdev)
8382 8386
8383 pci_disable_pcie_error_reporting(pdev); 8387 pci_disable_pcie_error_reporting(pdev);
8384 8388
8385 pci_disable_device(pdev); 8389 if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
8390 pci_disable_device(pdev);
8386} 8391}
8387 8392
8388/** 8393/**
@@ -8489,14 +8494,20 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
8489 8494
8490skip_bad_vf_detection: 8495skip_bad_vf_detection:
8491#endif /* CONFIG_PCI_IOV */ 8496#endif /* CONFIG_PCI_IOV */
8497 rtnl_lock();
8492 netif_device_detach(netdev); 8498 netif_device_detach(netdev);
8493 8499
8494 if (state == pci_channel_io_perm_failure) 8500 if (state == pci_channel_io_perm_failure) {
8501 rtnl_unlock();
8495 return PCI_ERS_RESULT_DISCONNECT; 8502 return PCI_ERS_RESULT_DISCONNECT;
8503 }
8496 8504
8497 if (netif_running(netdev)) 8505 if (netif_running(netdev))
8498 ixgbe_down(adapter); 8506 ixgbe_down(adapter);
8499 pci_disable_device(pdev); 8507
8508 if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
8509 pci_disable_device(pdev);
8510 rtnl_unlock();
8500 8511
8501 /* Request a slot reset. */ 8512 /* Request a slot reset. */
8502 return PCI_ERS_RESULT_NEED_RESET; 8513 return PCI_ERS_RESULT_NEED_RESET;
@@ -8518,6 +8529,8 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
8518 e_err(probe, "Cannot re-enable PCI device after reset.\n"); 8529 e_err(probe, "Cannot re-enable PCI device after reset.\n");
8519 result = PCI_ERS_RESULT_DISCONNECT; 8530 result = PCI_ERS_RESULT_DISCONNECT;
8520 } else { 8531 } else {
8532 smp_mb__before_clear_bit();
8533 clear_bit(__IXGBE_DISABLED, &adapter->state);
8521 adapter->hw.hw_addr = adapter->io_addr; 8534 adapter->hw.hw_addr = adapter->io_addr;
8522 pci_set_master(pdev); 8535 pci_set_master(pdev);
8523 pci_restore_state(pdev); 8536 pci_restore_state(pdev);