Skip to content

Commit f838a63

Browse files
dawid-lukwinskikuba-moo
authored andcommitted
i40e: Fix erroneous adapter reinitialization during recovery process
Fix an issue when driver incorrectly detects state of recovery process and erroneously reinitializes interrupts, which results in a kernel error and call trace message. The issue was caused by a combination of two factors: 1. Assuming the EMP reset issued after completing firmware recovery means the whole recovery process is complete. 2. Erroneous reinitialization of interrupt vector after detecting the above mentioned EMP reset. Fixes (1) by changing how recovery state change is detected and (2) by adjusting the conditional expression to ensure using proper interrupt reinitialization method, depending on the situation. Fixes: 4ff0ee1 ("i40e: Introduce recovery mode support") Signed-off-by: Dawid Lukwinski <[email protected]> Signed-off-by: Jan Sokolowski <[email protected]> Tested-by: Konrad Jankowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 3696c95 commit f838a63

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10650,21 +10650,19 @@ static int i40e_reset(struct i40e_pf *pf)
1065010650
**/
1065110651
static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
1065210652
{
10653-
int old_recovery_mode_bit = test_bit(__I40E_RECOVERY_MODE, pf->state);
10653+
const bool is_recovery_mode_reported = i40e_check_recovery_mode(pf);
1065410654
struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
1065510655
struct i40e_hw *hw = &pf->hw;
1065610656
i40e_status ret;
1065710657
u32 val;
1065810658
int v;
1065910659

1066010660
if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) &&
10661-
i40e_check_recovery_mode(pf)) {
10661+
is_recovery_mode_reported)
1066210662
i40e_set_ethtool_ops(pf->vsi[pf->lan_vsi]->netdev);
10663-
}
1066410663

1066510664
if (test_bit(__I40E_DOWN, pf->state) &&
10666-
!test_bit(__I40E_RECOVERY_MODE, pf->state) &&
10667-
!old_recovery_mode_bit)
10665+
!test_bit(__I40E_RECOVERY_MODE, pf->state))
1066810666
goto clear_recovery;
1066910667
dev_dbg(&pf->pdev->dev, "Rebuilding internal switch\n");
1067010668

@@ -10691,13 +10689,12 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
1069110689
* accordingly with regard to resources initialization
1069210690
* and deinitialization
1069310691
*/
10694-
if (test_bit(__I40E_RECOVERY_MODE, pf->state) ||
10695-
old_recovery_mode_bit) {
10692+
if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
1069610693
if (i40e_get_capabilities(pf,
1069710694
i40e_aqc_opc_list_func_capabilities))
1069810695
goto end_unlock;
1069910696

10700-
if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
10697+
if (is_recovery_mode_reported) {
1070110698
/* we're staying in recovery mode so we'll reinitialize
1070210699
* misc vector here
1070310700
*/

0 commit comments

Comments
 (0)