[PATCH 2/2] net/i40e: activate alarm if interrupt delivery unavailable

Ciara Loftus ciara.loftus at intel.com
Tue Jun 30 16:16:27 CEST 2026


If interrupt registration fails eg. on FreeBSD with nic_uio, and Rx
queue interrupts are configured (intr_conf.rxq != 0), the interrupt
handler is never called and ICR0 events, including AdminQ messages
carrying link state notifications, are never processed. In polling
mode (rxq == 0) a periodic alarm already drains these events, but in
the interrupt-enabled configuration no such fallback existed.

This gap has always existed but was partially masked by the blocking link
status poll in the i40e dev_start function, which would delay some time
until the link was up before returning. In this case, the link status was
typically correct after dev_start. However after that delay was removed in
111965395b ("net/i40e: fix blocking link wait on device start"), the link
status was often wrong after dev_start, and there was no mechanism to
self-correct.

Rather than restoring the blocking wait removed by that commit which would
re-impose a startup delay on every platform, activate the existing periodic
alarm on platforms where interrupt delivery is unavailable.

Fixes: 111965395b ("net/i40e: fix blocking link wait on device start")
Cc: stable at dpdk.org

Signed-off-by: Ciara Loftus <ciara.loftus at intel.com>
---
 drivers/net/intel/i40e/i40e_ethdev.c | 9 ++++++++-
 drivers/net/intel/i40e/i40e_ethdev.h | 2 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/intel/i40e/i40e_ethdev.c b/drivers/net/intel/i40e/i40e_ethdev.c
index b2694cd33a..86eb7468c8 100644
--- a/drivers/net/intel/i40e/i40e_ethdev.c
+++ b/drivers/net/intel/i40e/i40e_ethdev.c
@@ -2579,7 +2579,11 @@ i40e_dev_start(struct rte_eth_dev *dev)
 		i40e_dev_link_update(dev, !rte_intr_allow_others(intr_handle));
 		pf->mac_config_on_link_up = !dev->data->dev_link.link_status;
 		/* enable uio intr after callback register */
-		rte_intr_enable(intr_handle);
+		if (rte_intr_enable(intr_handle) != 0) {
+			pf->use_aq_polling = true;
+			rte_eal_alarm_set(I40E_ALARM_INTERVAL,
+					  i40e_dev_alarm_handler, dev);
+		}
 	}
 
 	i40e_filter_restore(pf);
@@ -2625,6 +2629,9 @@ i40e_dev_stop(struct rte_eth_dev *dev)
 	if (dev->data->dev_conf.intr_conf.rxq == 0) {
 		rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev);
 		rte_intr_enable(intr_handle);
+	} else if (pf->use_aq_polling) {
+		rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev);
+		pf->use_aq_polling = false;
 	}
 
 	/* Disable all queues */
diff --git a/drivers/net/intel/i40e/i40e_ethdev.h b/drivers/net/intel/i40e/i40e_ethdev.h
index 5a009393b0..9d9bde6aeb 100644
--- a/drivers/net/intel/i40e/i40e_ethdev.h
+++ b/drivers/net/intel/i40e/i40e_ethdev.h
@@ -1193,6 +1193,8 @@ struct i40e_pf {
 	bool fw8_3gt;
 	/* MAC config needs re-applying when link first comes up */
 	bool mac_config_on_link_up;
+	/* true when interrupt path unavailable */
+	bool use_aq_polling;
 
 	struct i40e_vf_msg_cfg vf_msg_cfg;
 	uint64_t prev_rx_bytes;
-- 
2.43.0



More information about the stable mailing list