Skip to content

Commit f0ee70a

Browse files
jacob-kellerJeff Kirsher
authored andcommitted
i40e: hold the RTNL lock while changing interrupt schemes
When we suspend and resume, we need to clear and re-enable the interrupt scheme. This was previously not done while holding the RTNL lock, which could be problematic, because we are actually destroying and re-creating queues. Hold the RTNL lock for the entire sequence of preparing for reset, and when resuming. This additionally protects the flags related to interrupt scheme under RTNL lock so that their modification is properly threaded. This is part of a larger effort to remove the need for cmpxchg64 in i40e_set_priv_flags(). Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
1 parent 5f76a70 commit f0ee70a

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14348,7 +14348,13 @@ static int __maybe_unused i40e_suspend(struct device *dev)
1434814348
if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE))
1434914349
i40e_enable_mc_magic_wake(pf);
1435014350

14351-
i40e_prep_for_reset(pf, false);
14351+
/* Since we're going to destroy queues during the
14352+
* i40e_clear_interrupt_scheme() we should hold the RTNL lock for this
14353+
* whole section
14354+
*/
14355+
rtnl_lock();
14356+
14357+
i40e_prep_for_reset(pf, true);
1435214358

1435314359
wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
1435414360
wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));
@@ -14360,6 +14366,8 @@ static int __maybe_unused i40e_suspend(struct device *dev)
1436014366
*/
1436114367
i40e_clear_interrupt_scheme(pf);
1436214368

14369+
rtnl_unlock();
14370+
1436314371
return 0;
1436414372
}
1436514373

@@ -14377,6 +14385,11 @@ static int __maybe_unused i40e_resume(struct device *dev)
1437714385
if (!test_bit(__I40E_SUSPENDED, pf->state))
1437814386
return 0;
1437914387

14388+
/* We need to hold the RTNL lock prior to restoring interrupt schemes,
14389+
* since we're going to be restoring queues
14390+
*/
14391+
rtnl_lock();
14392+
1438014393
/* We cleared the interrupt scheme when we suspended, so we need to
1438114394
* restore it now to resume device functionality.
1438214395
*/
@@ -14387,7 +14400,9 @@ static int __maybe_unused i40e_resume(struct device *dev)
1438714400
}
1438814401

1438914402
clear_bit(__I40E_DOWN, pf->state);
14390-
i40e_reset_and_rebuild(pf, false, false);
14403+
i40e_reset_and_rebuild(pf, false, true);
14404+
14405+
rtnl_unlock();
1439114406

1439214407
/* Clear suspended state last after everything is recovered */
1439314408
clear_bit(__I40E_SUSPENDED, pf->state);

0 commit comments

Comments
 (0)