i40e: prevent overlapping tx_timeout recover
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: Alan Brady <alan.brady@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
7cd8eb0861
commit
d5585b7b68
2 changed files with 6 additions and 0 deletions
|
|
@ -122,6 +122,7 @@ enum i40e_state_t {
|
|||
__I40E_MDD_EVENT_PENDING,
|
||||
__I40E_VFLR_EVENT_PENDING,
|
||||
__I40E_RESET_RECOVERY_PENDING,
|
||||
__I40E_TIMEOUT_RECOVERY_PENDING,
|
||||
__I40E_MISC_IRQ_REQUESTED,
|
||||
__I40E_RESET_INTR_RECEIVED,
|
||||
__I40E_REINIT_REQUESTED,
|
||||
|
|
|
|||
|
|
@ -338,6 +338,10 @@ static void i40e_tx_timeout(struct net_device *netdev)
|
|||
(pf->tx_timeout_last_recovery + netdev->watchdog_timeo)))
|
||||
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) {
|
||||
head = i40e_get_head(tx_ring);
|
||||
/* Read interrupt register */
|
||||
|
|
@ -9631,6 +9635,7 @@ end_core_reset:
|
|||
clear_bit(__I40E_RESET_FAILED, pf->state);
|
||||
clear_recovery:
|
||||
clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
|
||||
clear_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue