Commit aa422af6 authored by Alan Brady's avatar Alan Brady Committed by Greg Kroah-Hartman

i40e: prevent overlapping tx_timeout recover

[ Upstream commit d5585b7b ]

If a TX hang occurs, we attempt to recover by incrementally resetting.
If we're starved for CPU time, it's possible the reset doesn't actually
complete (or even fire) before another tx_timeout fires causing us to
fly through the different resets without actually doing them.

This adds a bit to set and check if a timeout recovery is already
pending and, if so, bail out of tx_timeout.  The bit will get cleared at
the end of i40e_rebuild when reset is complete.
Signed-off-by: default avatarAlan Brady <alan.brady@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 5a6b7e1b
...@@ -122,6 +122,7 @@ enum i40e_state_t { ...@@ -122,6 +122,7 @@ enum i40e_state_t {
__I40E_MDD_EVENT_PENDING, __I40E_MDD_EVENT_PENDING,
__I40E_VFLR_EVENT_PENDING, __I40E_VFLR_EVENT_PENDING,
__I40E_RESET_RECOVERY_PENDING, __I40E_RESET_RECOVERY_PENDING,
__I40E_TIMEOUT_RECOVERY_PENDING,
__I40E_MISC_IRQ_REQUESTED, __I40E_MISC_IRQ_REQUESTED,
__I40E_RESET_INTR_RECEIVED, __I40E_RESET_INTR_RECEIVED,
__I40E_REINIT_REQUESTED, __I40E_REINIT_REQUESTED,
......
...@@ -336,6 +336,10 @@ static void i40e_tx_timeout(struct net_device *netdev) ...@@ -336,6 +336,10 @@ static void i40e_tx_timeout(struct net_device *netdev)
(pf->tx_timeout_last_recovery + netdev->watchdog_timeo))) (pf->tx_timeout_last_recovery + netdev->watchdog_timeo)))
return; /* don't do any new action before the next timeout */ return; /* don't do any new action before the next timeout */
/* don't kick off another recovery if one is already pending */
if (test_and_set_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state))
return;
if (tx_ring) { if (tx_ring) {
head = i40e_get_head(tx_ring); head = i40e_get_head(tx_ring);
/* Read interrupt register */ /* Read interrupt register */
...@@ -9566,6 +9570,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) ...@@ -9566,6 +9570,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
clear_bit(__I40E_RESET_FAILED, pf->state); clear_bit(__I40E_RESET_FAILED, pf->state);
clear_recovery: clear_recovery:
clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state); clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
clear_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment