aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2015-01-29 02:17:20 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-02-23 20:13:21 -0500
commit54e16f64f0c494b78e3872612e45d002d220664d (patch)
tree946ed2d338485f17b3d02cf9022bff7bac7fcd35 /drivers/net/ethernet/intel
parentac833bbf7958bbdd416d6027b98763a231bc8f15 (diff)
i40evf: don't wait forever
Under rare circumstances, after a reset, set_rx_mode might get called while the watchdog is running, which will cause a deadlock on the critical section lock. To correct this, add a counter and give up trying to get the lock after fifty tries. Log a message if this happens but don't take any other action. Because this happens after a reset, all of the Rx filters are still in place and the device won't lose connectivity. We can also get stuck during shutdown, if the PF has stopped communicating with us, or if a reset is occurring. If we can't get the lock after a reasonable amount of time, just error out. Something else bad is happening anyway, so adding this filter is the least of our concern right now. Change-ID: I159731e2a82a06b389ee31b34ce336548e05baa0 Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Tested-by: Jim Young <james.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 1257577148ea..e089e8f98413 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -761,13 +761,17 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
761 u8 *macaddr) 761 u8 *macaddr)
762{ 762{
763 struct i40evf_mac_filter *f; 763 struct i40evf_mac_filter *f;
764 int count = 50;
764 765
765 if (!macaddr) 766 if (!macaddr)
766 return NULL; 767 return NULL;
767 768
768 while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, 769 while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
769 &adapter->crit_section)) 770 &adapter->crit_section)) {
770 udelay(1); 771 udelay(1);
772 if (--count == 0)
773 return NULL;
774 }
771 775
772 f = i40evf_find_filter(adapter, macaddr); 776 f = i40evf_find_filter(adapter, macaddr);
773 if (!f) { 777 if (!f) {
@@ -828,6 +832,7 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
828 struct i40evf_mac_filter *f, *ftmp; 832 struct i40evf_mac_filter *f, *ftmp;
829 struct netdev_hw_addr *uca; 833 struct netdev_hw_addr *uca;
830 struct netdev_hw_addr *mca; 834 struct netdev_hw_addr *mca;
835 int count = 50;
831 836
832 /* add addr if not already in the filter list */ 837 /* add addr if not already in the filter list */
833 netdev_for_each_uc_addr(uca, netdev) { 838 netdev_for_each_uc_addr(uca, netdev) {
@@ -838,8 +843,14 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
838 } 843 }
839 844
840 while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, 845 while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
841 &adapter->crit_section)) 846 &adapter->crit_section)) {
842 udelay(1); 847 udelay(1);
848 if (--count == 0) {
849 dev_err(&adapter->pdev->dev,
850 "Failed to get lock in %s\n", __func__);
851 return;
852 }
853 }
843 /* remove filter if not in netdev list */ 854 /* remove filter if not in netdev list */
844 list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { 855 list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
845 bool found = false; 856 bool found = false;