[Intel-wired-lan] [PATCH iwl-net v2 4/5] i40e: replace reset polling with wait-bit synchronization
[email protected] Wed, 5 Aug 2026 14:51:31 +0800
| Newsgroups | org.osuosl.intel-wired-lan,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
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