提交 54e16f64 编写于 作者: M Mitch Williams 提交者: Jeff Kirsher

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: NMitch Williams <mitch.a.williams@intel.com>
Tested-by: NJim Young <james.m.young@intel.com>
Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
上级 ac833bbf
...@@ -761,13 +761,17 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter, ...@@ -761,13 +761,17 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
u8 *macaddr) u8 *macaddr)
{ {
struct i40evf_mac_filter *f; struct i40evf_mac_filter *f;
int count = 50;
if (!macaddr) if (!macaddr)
return NULL; return NULL;
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section)) &adapter->crit_section)) {
udelay(1); udelay(1);
if (--count == 0)
return NULL;
}
f = i40evf_find_filter(adapter, macaddr); f = i40evf_find_filter(adapter, macaddr);
if (!f) { if (!f) {
...@@ -828,6 +832,7 @@ static void i40evf_set_rx_mode(struct net_device *netdev) ...@@ -828,6 +832,7 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
struct i40evf_mac_filter *f, *ftmp; struct i40evf_mac_filter *f, *ftmp;
struct netdev_hw_addr *uca; struct netdev_hw_addr *uca;
struct netdev_hw_addr *mca; struct netdev_hw_addr *mca;
int count = 50;
/* add addr if not already in the filter list */ /* add addr if not already in the filter list */
netdev_for_each_uc_addr(uca, netdev) { netdev_for_each_uc_addr(uca, netdev) {
...@@ -838,8 +843,14 @@ static void i40evf_set_rx_mode(struct net_device *netdev) ...@@ -838,8 +843,14 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
} }
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section)) &adapter->crit_section)) {
udelay(1); udelay(1);
if (--count == 0) {
dev_err(&adapter->pdev->dev,
"Failed to get lock in %s\n", __func__);
return;
}
}
/* remove filter if not in netdev list */ /* remove filter if not in netdev list */
list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
bool found = false; bool found = false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册