Rx interrupt enable and disable wait for reset_ops_lock and then return -EBUSY if a reset is in progress. The reset thread holds that lock across the teardown (mana_dev_stop(), the RESET_ENTER request to secondary processes, mana_dev_close()) and across the re-probe, and each request to the secondaries may take up to MANA_MP_REQ_TIMEOUT_SEC. An lcore that calls rx_intr_enable or rx_intr_disable during one of those steps blocks for that long, only to get -EBUSY.
Retry the trylock while the device is active, and return -EBUSY as soon as it is not. Outside a reset the lock is held only by another queue's doorbell write or event read, so the wait stays short; once a reset has started, the caller returns at once. Suggested-by: Wei Hu <[email protected]> Signed-off-by: Orgad Shaneh <[email protected]> --- Applies on next-net for-main, on top of efa36b47334d ("net/mana: fix Rx interrupt enable failing on lock contention"). Squash it into that commit if you prefer. Follow-up to Wei's review and the AI review note: https://inbox.dpdk.org/dev/[email protected]/ Builds with meson -Dwerror=true (gcc 14, rdma-core 56). With no reset in progress the calls take the lock and run the same code as before, so the Azure results in efa36b47334d still apply. A MANA reset cannot be triggered on demand on Azure, so the reset path is untested. The burst_state gate stays a possible follow-up for main. drivers/net/mana/mana.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/mana/mana.c b/drivers/net/mana/mana.c index f624cde6b9..eea9dac253 100644 --- a/drivers/net/mana/mana.c +++ b/drivers/net/mana/mana.c @@ -451,14 +451,21 @@ mana_reset_trylock(struct mana_priv *priv) } /* - * Like mana_reset_trylock(), but wait for the lock. Used by Rx interrupt - * enable/disable, which every queue calls on each sleep and wakeup: they - * must not fail just because another queue holds the lock for a moment. + * Like mana_reset_trylock(), but wait while another queue holds the lock. + * Used by Rx interrupt enable/disable, which every queue calls on each + * sleep and wakeup: they must not fail just because another queue holds + * the lock for a moment. Once a reset has started, fail at once instead + * of waiting for its teardown or re-probe step. */ static int mana_reset_lock(struct mana_priv *priv) { - pthread_mutex_lock(&priv->reset_ops_lock); + while (pthread_mutex_trylock(&priv->reset_ops_lock)) { + if (rte_atomic_load_explicit(&priv->dev_state, + rte_memory_order_relaxed) != MANA_DEV_ACTIVE) + return -EBUSY; + rte_pause(); + } if (rte_atomic_load_explicit(&priv->dev_state, rte_memory_order_acquire) != MANA_DEV_ACTIVE) { -- 2.52.0

