On 26. 07. 23 22:43, Aleksandr Loktionov wrote:
Fix livelocks by acquiring rtnl_lock() before any reset related operations.
Add rtnl_lock()/rtnl_unlock() at top/bottom of i40e_reset_subtask()
Add check for __I40E_RESET_INTR_RECEIVED bit.
Add re-entry guard by fast return in case reset is already in progress.

Fixes: 373149fc99a0 ("i40e: Decrease the scope of rtnl lock")
Signed-off-by: Aleksandr Loktionov <aleksandr.loktio...@intel.com>
---
v3->v4 fix | position in the code
v2->v3 fix typo in the commit message
v1->v2 * apply on 
https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue.git
---
---
  drivers/net/ethernet/intel/i40e/i40e_main.c | 39 +++++++++++----------
  1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c 
b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 7c30abd..164f7c6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -10011,42 +10011,44 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
  {
        u32 reset_flags = 0;
- if (test_bit(__I40E_REINIT_REQUESTED, pf->state)) {
+       if (test_and_clear_bit(__I40E_REINIT_REQUESTED, pf->state))
                reset_flags |= BIT(__I40E_REINIT_REQUESTED);
-               clear_bit(__I40E_REINIT_REQUESTED, pf->state);
-       }
-       if (test_bit(__I40E_PF_RESET_REQUESTED, pf->state)) {
+       if (test_and_clear_bit(__I40E_PF_RESET_REQUESTED, pf->state))
                reset_flags |= BIT(__I40E_PF_RESET_REQUESTED);
-               clear_bit(__I40E_PF_RESET_REQUESTED, pf->state);
-       }
-       if (test_bit(__I40E_CORE_RESET_REQUESTED, pf->state)) {
+       if (test_and_clear_bit(__I40E_CORE_RESET_REQUESTED, pf->state))
                reset_flags |= BIT(__I40E_CORE_RESET_REQUESTED);
-               clear_bit(__I40E_CORE_RESET_REQUESTED, pf->state);
-       }
-       if (test_bit(__I40E_GLOBAL_RESET_REQUESTED, pf->state)) {
+       if (test_and_clear_bit(__I40E_GLOBAL_RESET_REQUESTED, pf->state))
                reset_flags |= BIT(__I40E_GLOBAL_RESET_REQUESTED);
-               clear_bit(__I40E_GLOBAL_RESET_REQUESTED, pf->state);
-       }
-       if (test_bit(__I40E_DOWN_REQUESTED, pf->state)) {
+       if (test_and_clear_bit(__I40E_DOWN_REQUESTED, pf->state))
                reset_flags |= BIT(__I40E_DOWN_REQUESTED);
-               clear_bit(__I40E_DOWN_REQUESTED, pf->state);
-       }
+       if (test_and_clear_bit(__I40E_RESET_INTR_RECEIVED, pf->state))
+               reset_flags |= BIT(__I40E_RESET_INTR_RECEIVED);
+
+       if (!(reset_flags & (BIT(__I40E_PF_RESET_REQUESTED) |
+                            BIT(__I40E_CORE_RESET_REQUESTED) |
+                            BIT(__I40E_GLOBAL_RESET_REQUESTED) |
+                            BIT(__I40E_RESET_INTR_RECEIVED))))
+               return;
+
+       rtnl_lock();
/* If there's a recovery already waiting, it takes
         * precedence before starting a new reset sequence.
         */
-       if (test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) {
+       if (reset_flags & BIT(__I40E_RESET_INTR_RECEIVED)) {
                i40e_prep_for_reset(pf);
                i40e_reset(pf);
-               i40e_rebuild(pf, false, false);
+               i40e_rebuild(pf, false, true);
        }
/* If we're already down or resetting, just bail */
        if (reset_flags &&
            !test_bit(__I40E_DOWN, pf->state) &&
            !test_bit(__I40E_CONFIG_BUSY, pf->state)) {
-               i40e_do_reset(pf, reset_flags, false);
+               i40e_do_reset(pf, reset_flags, true);
        }
+
+       rtnl_unlock();
  }
/**
@@ -10694,7 +10696,6 @@ static void i40e_prep_for_reset(struct i40e_pf *pf)
        int ret = 0;
        u32 v;
- clear_bit(__I40E_RESET_INTR_RECEIVED, pf->state);
        if (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
                return;
        if (i40e_check_asq_alive(&pf->hw))

Tony, why this is marked in IWL patchwork as ChangesRequested? There were no comments and the patch disappeared from dev-queue. Are you planning to process it?

Thanks,
Ivan

Reply via email to