0009-i40e-prevent-overlapping-tx_timeout-recover.patch 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Alan Brady <[email protected]>
  3. Date: Mon, 29 Oct 2018 11:27:21 -0700
  4. Subject: [PATCH] i40e: prevent overlapping tx_timeout recover
  5. If a TX hang occurs, we attempt to recover by incrementally resetting.
  6. If we're starved for CPU time, it's possible the reset doesn't actually
  7. complete (or even fire) before another tx_timeout fires causing us to
  8. fly through the different resets without actually doing them.
  9. This adds a bit to set and check if a timeout recovery is already
  10. pending and, if so, bail out of tx_timeout. The bit will get cleared at
  11. the end of i40e_rebuild when reset is complete.
  12. Signed-off-by: Alan Brady <[email protected]>
  13. Tested-by: Andrew Bowers <[email protected]>
  14. Signed-off-by: Jeff Kirsher <[email protected]>
  15. Signed-off-by: Thomas Lamprecht <[email protected]>
  16. ---
  17. drivers/net/ethernet/intel/i40e/i40e.h | 1 +
  18. drivers/net/ethernet/intel/i40e/i40e_main.c | 5 +++++
  19. 2 files changed, 6 insertions(+)
  20. diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
  21. index e019baa905c5..80114d6a910a 100644
  22. --- a/drivers/net/ethernet/intel/i40e/i40e.h
  23. +++ b/drivers/net/ethernet/intel/i40e/i40e.h
  24. @@ -145,6 +145,7 @@ enum i40e_state_t {
  25. __I40E_MDD_EVENT_PENDING,
  26. __I40E_VFLR_EVENT_PENDING,
  27. __I40E_RESET_RECOVERY_PENDING,
  28. + __I40E_TIMEOUT_RECOVERY_PENDING,
  29. __I40E_MISC_IRQ_REQUESTED,
  30. __I40E_RESET_INTR_RECEIVED,
  31. __I40E_REINIT_REQUESTED,
  32. diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
  33. index 7895a0af37e6..874fd143c351 100644
  34. --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
  35. +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
  36. @@ -365,6 +365,10 @@ static void i40e_tx_timeout(struct net_device *netdev)
  37. (pf->tx_timeout_last_recovery + netdev->watchdog_timeo)))
  38. return; /* don't do any new action before the next timeout */
  39. + /* don't kick off another recovery if one is already pending */
  40. + if (test_and_set_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state))
  41. + return;
  42. +
  43. if (tx_ring) {
  44. head = i40e_get_head(tx_ring);
  45. /* Read interrupt register */
  46. @@ -9478,6 +9482,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
  47. clear_bit(__I40E_RESET_FAILED, pf->state);
  48. clear_recovery:
  49. clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
  50. + clear_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state);
  51. }
  52. /**