aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMark Rustad <mark.d.rustad@intel.com>2014-03-11 20:38:45 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-03-31 18:48:03 -0400
commitbc0c715167c68ac2e737e221a80fc2a413f48155 (patch)
tree85abedb87258ef964615a61ea661fcd5a719331c /drivers/net
parent41c62843eb6a0ea3e2f1e06ca3ec7b2f64452f7b (diff)
ixgbevf: 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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c22
2 files changed, 18 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index a08bd7c46766..e7e7d695816b 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -419,6 +419,7 @@ enum ixbgevf_state_t {
419 __IXGBEVF_TESTING, 419 __IXGBEVF_TESTING,
420 __IXGBEVF_RESETTING, 420 __IXGBEVF_RESETTING,
421 __IXGBEVF_DOWN, 421 __IXGBEVF_DOWN,
422 __IXGBEVF_DISABLED,
422 __IXGBEVF_REMOVING, 423 __IXGBEVF_REMOVING,
423}; 424};
424 425
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 5d9375981713..4ba139b2d25a 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3329,7 +3329,8 @@ static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
3329 return retval; 3329 return retval;
3330 3330
3331#endif 3331#endif
3332 pci_disable_device(pdev); 3332 if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state))
3333 pci_disable_device(pdev);
3333 3334
3334 return 0; 3335 return 0;
3335} 3336}
@@ -3353,6 +3354,8 @@ static int ixgbevf_resume(struct pci_dev *pdev)
3353 dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n"); 3354 dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
3354 return err; 3355 return err;
3355 } 3356 }
3357 smp_mb__before_clear_bit();
3358 clear_bit(__IXGBEVF_DISABLED, &adapter->state);
3356 pci_set_master(pdev); 3359 pci_set_master(pdev);
3357 3360
3358 ixgbevf_reset(adapter); 3361 ixgbevf_reset(adapter);
@@ -3607,7 +3610,8 @@ err_alloc_etherdev:
3607 pci_release_regions(pdev); 3610 pci_release_regions(pdev);
3608err_pci_reg: 3611err_pci_reg:
3609err_dma: 3612err_dma:
3610 pci_disable_device(pdev); 3613 if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state))
3614 pci_disable_device(pdev);
3611 return err; 3615 return err;
3612} 3616}
3613 3617
@@ -3645,7 +3649,8 @@ static void ixgbevf_remove(struct pci_dev *pdev)
3645 3649
3646 free_netdev(netdev); 3650 free_netdev(netdev);
3647 3651
3648 pci_disable_device(pdev); 3652 if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state))
3653 pci_disable_device(pdev);
3649} 3654}
3650 3655
3651/** 3656/**
@@ -3662,15 +3667,20 @@ static pci_ers_result_t ixgbevf_io_error_detected(struct pci_dev *pdev,
3662 struct net_device *netdev = pci_get_drvdata(pdev); 3667 struct net_device *netdev = pci_get_drvdata(pdev);
3663 struct ixgbevf_adapter *adapter = netdev_priv(netdev); 3668 struct ixgbevf_adapter *adapter = netdev_priv(netdev);
3664 3669
3670 rtnl_lock();
3665 netif_device_detach(netdev); 3671 netif_device_detach(netdev);
3666 3672
3667 if (state == pci_channel_io_perm_failure) 3673 if (state == pci_channel_io_perm_failure) {
3674 rtnl_unlock();
3668 return PCI_ERS_RESULT_DISCONNECT; 3675 return PCI_ERS_RESULT_DISCONNECT;
3676 }
3669 3677
3670 if (netif_running(netdev)) 3678 if (netif_running(netdev))
3671 ixgbevf_down(adapter); 3679 ixgbevf_down(adapter);
3672 3680
3673 pci_disable_device(pdev); 3681 if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state))
3682 pci_disable_device(pdev);
3683 rtnl_unlock();
3674 3684
3675 /* Request a slot slot reset. */ 3685 /* Request a slot slot reset. */
3676 return PCI_ERS_RESULT_NEED_RESET; 3686 return PCI_ERS_RESULT_NEED_RESET;
@@ -3694,6 +3704,8 @@ static pci_ers_result_t ixgbevf_io_slot_reset(struct pci_dev *pdev)
3694 return PCI_ERS_RESULT_DISCONNECT; 3704 return PCI_ERS_RESULT_DISCONNECT;
3695 } 3705 }
3696 3706
3707 smp_mb__before_clear_bit();
3708 clear_bit(__IXGBEVF_DISABLED, &adapter->state);
3697 pci_set_master(pdev); 3709 pci_set_master(pdev);
3698 3710
3699 ixgbevf_reset(adapter); 3711 ixgbevf_reset(adapter);