From: Xuanqiang Luo <[email protected]>
i40e_remove() polls on RESET_RECOVERY_PENDING with a fixed sleep while
waiting for an existing reset owner. This adds teardown latency and does
not provide a wait queue for the reset owner to wake.
Use wait_on_bit_lock() so removal sleeps until the reset owner releases the
bit and then atomically claims it. Pair the reset release paths with
clear_and_wake_up_bit() to provide the required release and wakeup
semantics.
Fixes: 5b6d4a7f20b0 ("i40e: Fix crash during removing i40e driver")
Signed-off-by: Xuanqiang Luo <[email protected]>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 5922f83f324ae..c19d4c81d6532 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7,6 +7,7 @@
#include <linux/if_bridge.h>
#include <linux/if_macvlan.h>
#include <linux/module.h>
+#include <linux/wait_bit.h>
#include <net/pkt_cls.h>
#include <net/xdp_sock_drv.h>
@@ -10822,7 +10823,8 @@ static int i40e_reset(struct i40e_pf *pf)
if (ret) {
dev_info(&pf->pdev->dev, "PF reset failed, %d\n", ret);
set_bit(__I40E_RESET_FAILED, pf->state);
- clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
+ clear_and_wake_up_bit(__I40E_RESET_RECOVERY_PENDING,
+ pf->state);
} else {
pf->pfr_count++;
}
@@ -11115,7 +11117,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
end_core_reset:
clear_bit(__I40E_RESET_FAILED, pf->state);
clear_recovery:
- clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
+ clear_and_wake_up_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
clear_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state);
}
@@ -16169,8 +16171,8 @@ static void i40e_remove(struct pci_dev *pdev)
disable_work_sync(&pf->service_task);
/* Wait for any reset owner before tearing down device resources. */
- while (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
- usleep_range(1000, 2000);
+ wait_on_bit_lock(pf->state, __I40E_RESET_RECOVERY_PENDING,
+ TASK_UNINTERRUPTIBLE);
set_bit(__I40E_IN_REMOVE, pf->state);
i40e_dbg_pf_exit(pf);
--
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.