Commit d20cd745 authored by Vasundhara Volam's avatar Vasundhara Volam Committed by Jakub Kicinski

bnxt_en: Fix race between firmware reset and driver remove.

The driver's error recovery reset sequence can take many seconds to
complete and only the critical sections are protected by rtnl_lock.
A recent change has introduced a regression in this sequence.

bnxt_remove_one() may be called while the recovery is in progress.
Normally, unregister_netdev() would cause bnxt_close_nic() to be
called and this would cause the error recovery to safely abort
with the BNXT_STATE_ABORT_ERR flag set in bnxt_close_nic().

Recently, we added bnxt_reinit_after_abort() to allow the user to
reopen the device after an aborted recovery.  This causes the
regression in the scenario described above because we would
attempt to re-open even after the netdev has been unregistered.

Fix it by checking the netdev reg_state in
bnxt_reinit_after_abort() and abort if it is unregistered.

Fixes: 6882c36c ("bnxt_en: attempt to reinitialize after aborted reset")
Signed-off-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 82adc457
...@@ -9890,6 +9890,9 @@ static int bnxt_reinit_after_abort(struct bnxt *bp) ...@@ -9890,6 +9890,9 @@ static int bnxt_reinit_after_abort(struct bnxt *bp)
if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
return -EBUSY; return -EBUSY;
if (bp->dev->reg_state == NETREG_UNREGISTERED)
return -ENODEV;
rc = bnxt_fw_init_one(bp); rc = bnxt_fw_init_one(bp);
if (!rc) { if (!rc) {
bnxt_clear_int_mode(bp); bnxt_clear_int_mode(bp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment