From: Ciara Loftus <ciara.loftus@intel.com>
To: dev@dpdk.org
Cc: Ciara Loftus <ciara.loftus@intel.com>, stable@dpdk.org
Subject: [PATCH 1/2] net/ice: poll AdminQ if interrupt delivery unavailable
Date: Tue, 30 Jun 2026 14:16:26 +0000 [thread overview]
Message-ID: <20260630141627.1035420-2-ciara.loftus@intel.com> (raw)
In-Reply-To: <20260630141627.1035420-1-ciara.loftus@intel.com>
If interrupt registration fails eg. on FreeBSD with nic_uio, the ice
interrupt handler is never called and AdminQ messages, including
unsolicited link state notifications, are never processed.
This gap has always existed but was partially masked by the blocking link
status poll in the ice 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
2dd7e99855 ("net/ice: revert fix link up when starting device"), 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, instead activate a
periodic alarm that drains the AdminQ on a 50ms interval, replicating the
role of the interrupt handler on platforms where interrupt delivery is not
supported.
Fixes: 2dd7e99855 ("net/ice: revert fix link up when starting device")
Cc: stable@dpdk.org
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
---
drivers/net/intel/ice/ice_ethdev.c | 45 +++++++++++++++++++++++++++++-
drivers/net/intel/ice/ice_ethdev.h | 1 +
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 022d92a2f6..447742ff8d 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -3,6 +3,7 @@
*/
#include <rte_string_fns.h>
+#include <rte_alarm.h>
#include <ethdev_pci.h>
#include <ctype.h>
@@ -108,7 +109,11 @@ enum ice_link_state_on_close {
#define ICE_RSS_LUT_GLOBAL_QUEUE_NB 64
+/* Polling interval used when the interrupt path is unavailable */
+#define ICE_AQ_ALARM_INTERVAL 50000 /* us */
+
static int ice_dev_configure(struct rte_eth_dev *dev);
+static void ice_aq_alarm_handler(void *param);
static int ice_dev_start(struct rte_eth_dev *dev);
static int ice_dev_stop(struct rte_eth_dev *dev);
static int ice_dev_close(struct rte_eth_dev *dev);
@@ -1473,6 +1478,28 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
}
}
+/*
+ * Alarm-based AdminQ polling handler that drains the AdminQ to process
+ * async events, then re-arms itself.
+ *
+ * @param param
+ * The address of parameter (struct rte_eth_dev *) registered before.
+ *
+ * @return
+ * void
+ */
+static void
+ice_aq_alarm_handler(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (!pf->adapter_stopped) {
+ ice_handle_aq_msg(dev);
+ rte_eal_alarm_set(ICE_AQ_ALARM_INTERVAL, ice_aq_alarm_handler, dev);
+ }
+}
+
/**
* Interrupt handler triggered by NIC for handling
* specific interrupt.
@@ -2913,6 +2940,11 @@ ice_dev_stop(struct rte_eth_dev *dev)
rte_intr_efd_disable(intr_handle);
rte_intr_vec_list_free(intr_handle);
+ if (pf->use_aq_polling) {
+ rte_eal_alarm_cancel(ice_aq_alarm_handler, dev);
+ pf->use_aq_polling = false;
+ }
+
pf->adapter_stopped = true;
dev->data->dev_started = 0;
@@ -4434,7 +4466,13 @@ ice_dev_start(struct rte_eth_dev *dev)
if (ice_rxq_intr_setup(dev))
return -EIO;
- rte_intr_enable(pci_dev->intr_handle);
+ /* Fall back to polling the AdminQ via an alarm on platforms where
+ * interrupt delivery is unavailable.
+ */
+ if (rte_intr_enable(pci_dev->intr_handle) != 0) {
+ pf->use_aq_polling = true;
+ rte_eal_alarm_set(ICE_AQ_ALARM_INTERVAL, ice_aq_alarm_handler, dev);
+ }
/* Enable receiving broadcast packets and transmitting packets */
ice_set_bit(ICE_PROMISC_BCAST_RX, pmask);
@@ -4497,6 +4535,11 @@ ice_dev_start(struct rte_eth_dev *dev)
for (i = 0; i < nb_txq; i++)
ice_tx_queue_stop(dev, i);
+ if (pf->use_aq_polling) {
+ rte_eal_alarm_cancel(ice_aq_alarm_handler, dev);
+ pf->use_aq_polling = false;
+ }
+
return -EIO;
}
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 20e8a13fe9..86b256fc3f 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -599,6 +599,7 @@ struct ice_pf {
struct ice_eth_stats internal_stats;
bool offset_loaded;
bool adapter_stopped;
+ bool use_aq_polling; /* true when interrupt path unavailable */
struct ice_flow_list flow_list;
rte_spinlock_t flow_ops_lock;
bool init_link_up;
--
2.43.0
next prev parent reply other threads:[~2026-06-30 14:16 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 14:16 [PATCH 0/2] net/intel: fix link status when interrupt delivery unavailable Ciara Loftus
2026-06-30 14:16 ` Ciara Loftus [this message]
2026-07-01 11:26 ` [PATCH 1/2] net/ice: poll AdminQ if " Bruce Richardson
2026-06-30 14:16 ` [PATCH 2/2] net/i40e: activate alarm " Ciara Loftus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260630141627.1035420-2-ciara.loftus@intel.com \
--to=ciara.loftus@intel.com \
--cc=dev@dpdk.org \
--cc=stable@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox