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>
This commit is contained in:
Родитель
ac833bbf79
Коммит
54e16f64f0
|
@ -761,13 +761,17 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
|
|||
u8 *macaddr)
|
||||
{
|
||||
struct i40evf_mac_filter *f;
|
||||
int count = 50;
|
||||
|
||||
if (!macaddr)
|
||||
return NULL;
|
||||
|
||||
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
|
||||
&adapter->crit_section))
|
||||
&adapter->crit_section)) {
|
||||
udelay(1);
|
||||
if (--count == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = i40evf_find_filter(adapter, macaddr);
|
||||
if (!f) {
|
||||
|
@ -828,6 +832,7 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
|
|||
struct i40evf_mac_filter *f, *ftmp;
|
||||
struct netdev_hw_addr *uca;
|
||||
struct netdev_hw_addr *mca;
|
||||
int count = 50;
|
||||
|
||||
/* add addr if not already in the filter list */
|
||||
netdev_for_each_uc_addr(uca, netdev) {
|
||||
|
@ -838,8 +843,14 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
|
|||
}
|
||||
|
||||
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
|
||||
&adapter->crit_section))
|
||||
&adapter->crit_section)) {
|
||||
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 */
|
||||
list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
|
||||
bool found = false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче