public inbox for dev@dpdk.org
 help / color / mirror / Atom feed
* [PATCH] net/ice: get link status updates via adminq message
@ 2026-02-27 11:02 Bruce Richardson
  2026-02-27 11:41 ` [PATCH v2] " Bruce Richardson
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-02-27 11:02 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Anatoly Burakov

Rather than relying directly on an interrupt we get link status updates
from the device firmware via adminq messages.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c | 48 ++++++++++--------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index e68f0cf707..75fff72b79 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -1397,7 +1397,9 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA, 0);
 	ICE_READ_REG(hw, PFINT_OICR);
 
-#ifdef ICE_LSE_SPT
+	/* Enable all OICR causes except link-state-change: LSC is delivered
+	 * as an unsolicited AdminQ get-link-status notification.
+	 */
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA,
 		      (uint32_t)(PFINT_OICR_ENA_INT_ENA_M &
 				 (~PFINT_OICR_LINK_STAT_CHANGE_M)));
@@ -1413,9 +1415,6 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 		      ((0 << PFINT_FW_CTL_ITR_INDX_S) &
 		       PFINT_FW_CTL_ITR_INDX_M) |
 		      PFINT_FW_CTL_CAUSE_ENA_M);
-#else
-	ICE_WRITE_REG(hw, PFINT_OICR_ENA, PFINT_OICR_ENA_INT_ENA_M);
-#endif
 
 	ICE_WRITE_REG(hw, GLINT_DYN_CTL(0),
 		      GLINT_DYN_CTL_INTENA_M |
@@ -1434,7 +1433,6 @@ ice_pf_disable_irq0(struct ice_hw *hw)
 	ice_flush(hw);
 }
 
-#ifdef ICE_LSE_SPT
 static void
 ice_handle_aq_msg(struct rte_eth_dev *dev)
 {
@@ -1453,10 +1451,9 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		ret = ice_clean_rq_elem(hw, cq, &event, &pending);
 
 		if (ret != ICE_SUCCESS) {
-			PMD_DRV_LOG(INFO,
-				    "Failed to read msg from AdminQ, "
-				    "adminq_err: %u",
-				    hw->adminq.sq_last_status);
+			if (hw->adminq.sq_last_status != 0)
+				PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ, adminq_err: %u",
+						hw->adminq.sq_last_status);
 			break;
 		}
 		opcode = rte_le_to_cpu_16(event.desc.opcode);
@@ -1475,7 +1472,6 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		}
 	}
 }
-#endif
 
 /**
  * Interrupt handler triggered by NIC for handling
@@ -1494,24 +1490,18 @@ ice_interrupt_handler(void *param)
 {
 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	uint32_t oicr;
 	uint32_t reg;
 	uint8_t pf_num;
 	uint8_t event;
 	uint16_t queue;
-	int ret;
-#ifdef ICE_LSE_SPT
-	uint32_t int_fw_ctl;
-#endif
 
 	/* Disable interrupt */
 	ice_pf_disable_irq0(hw);
 
 	/* read out interrupt causes */
 	oicr = ICE_READ_REG(hw, PFINT_OICR);
-#ifdef ICE_LSE_SPT
-	int_fw_ctl = ICE_READ_REG(hw, PFINT_FW_CTL);
-#endif
 
 	/* No interrupt event indicated */
 	if (!(oicr & PFINT_OICR_INTEVENT_M)) {
@@ -1519,20 +1509,8 @@ ice_interrupt_handler(void *param)
 		goto done;
 	}
 
-#ifdef ICE_LSE_SPT
-	if (int_fw_ctl & PFINT_FW_CTL_INTEVENT_M) {
-		PMD_DRV_LOG(INFO, "FW_CTL: link state change event");
-		ice_handle_aq_msg(dev);
-	}
-#else
-	if (oicr & PFINT_OICR_LINK_STAT_CHANGE_M) {
-		PMD_DRV_LOG(INFO, "OICR: link state change event");
-		ret = ice_link_update(dev, 0);
-		if (!ret)
-			rte_eth_dev_callback_process
-				(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
-	}
-#endif
+	/* Always drain the AdminQ on any misc interrupt. */
+	ice_handle_aq_msg(dev);
 
 	if (oicr & PFINT_OICR_MAL_DETECT_M) {
 		PMD_DRV_LOG(WARNING, "OICR: MDD event");
@@ -1581,7 +1559,10 @@ ice_interrupt_handler(void *param)
 done:
 	/* Enable interrupt */
 	ice_pf_enable_irq0(hw);
-	rte_intr_ack(dev->intr_handle);
+	rte_intr_ack(pci_dev->intr_handle);
+
+	/* Re-drain AdminQ to catch events that arrived during the CLEARPBA window */
+	ice_handle_aq_msg(dev);
 }
 
 static void
@@ -4393,6 +4374,7 @@ ice_dev_start(struct rte_eth_dev *dev)
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct ice_vsi *vsi = pf->main_vsi;
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	struct ice_adapter *ad =
 			ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	uint16_t nb_rxq = 0;
@@ -4443,6 +4425,8 @@ ice_dev_start(struct rte_eth_dev *dev)
 	if (ice_rxq_intr_setup(dev))
 		return -EIO;
 
+	rte_intr_enable(pci_dev->intr_handle);
+
 	/* Enable receiving broadcast packets and transmitting packets */
 	ice_set_bit(ICE_PROMISC_BCAST_RX, pmask);
 	ice_set_bit(ICE_PROMISC_BCAST_TX, pmask);
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v2] net/ice: get link status updates via adminq message
  2026-02-27 11:02 [PATCH] net/ice: get link status updates via adminq message Bruce Richardson
@ 2026-02-27 11:41 ` Bruce Richardson
  2026-03-02 11:48 ` [PATCH v3 0/2] " Bruce Richardson
  2026-03-03 16:21 ` [PATCH v4 0/2] " Bruce Richardson
  2 siblings, 0 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-02-27 11:41 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Anatoly Burakov

Rather than relying directly on an interrupt we get link status updates
from the device firmware via adminq messages.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
V2: rebase onto next-net-intel to avoid CI patch-apply issues
---
 drivers/net/intel/ice/ice_ethdev.c | 48 ++++++++++--------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index a59ca2e047..8286816f06 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -1397,7 +1397,9 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA, 0);
 	ICE_READ_REG(hw, PFINT_OICR);
 
-#ifdef ICE_LSE_SPT
+	/* Enable all OICR causes except link-state-change: LSC is delivered
+	 * as an unsolicited AdminQ get-link-status notification.
+	 */
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA,
 		      (uint32_t)(PFINT_OICR_ENA_INT_ENA_M &
 				 (~PFINT_OICR_LINK_STAT_CHANGE_M)));
@@ -1413,9 +1415,6 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 		      ((0 << PFINT_FW_CTL_ITR_INDX_S) &
 		       PFINT_FW_CTL_ITR_INDX_M) |
 		      PFINT_FW_CTL_CAUSE_ENA_M);
-#else
-	ICE_WRITE_REG(hw, PFINT_OICR_ENA, PFINT_OICR_ENA_INT_ENA_M);
-#endif
 
 	ICE_WRITE_REG(hw, GLINT_DYN_CTL(0),
 		      GLINT_DYN_CTL_INTENA_M |
@@ -1434,7 +1433,6 @@ ice_pf_disable_irq0(struct ice_hw *hw)
 	ice_flush(hw);
 }
 
-#ifdef ICE_LSE_SPT
 static void
 ice_handle_aq_msg(struct rte_eth_dev *dev)
 {
@@ -1453,10 +1451,9 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		ret = ice_clean_rq_elem(hw, cq, &event, &pending);
 
 		if (ret != ICE_SUCCESS) {
-			PMD_DRV_LOG(INFO,
-				    "Failed to read msg from AdminQ, "
-				    "adminq_err: %u",
-				    hw->adminq.sq_last_status);
+			if (hw->adminq.sq_last_status != 0)
+				PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ, adminq_err: %u",
+						hw->adminq.sq_last_status);
 			break;
 		}
 		opcode = rte_le_to_cpu_16(event.desc.opcode);
@@ -1475,7 +1472,6 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		}
 	}
 }
-#endif
 
 /**
  * Interrupt handler triggered by NIC for handling
@@ -1494,24 +1490,18 @@ ice_interrupt_handler(void *param)
 {
 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	uint32_t oicr;
 	uint32_t reg;
 	uint8_t pf_num;
 	uint8_t event;
 	uint16_t queue;
-	int ret;
-#ifdef ICE_LSE_SPT
-	uint32_t int_fw_ctl;
-#endif
 
 	/* Disable interrupt */
 	ice_pf_disable_irq0(hw);
 
 	/* read out interrupt causes */
 	oicr = ICE_READ_REG(hw, PFINT_OICR);
-#ifdef ICE_LSE_SPT
-	int_fw_ctl = ICE_READ_REG(hw, PFINT_FW_CTL);
-#endif
 
 	/* No interrupt event indicated */
 	if (!(oicr & PFINT_OICR_INTEVENT_M)) {
@@ -1519,20 +1509,8 @@ ice_interrupt_handler(void *param)
 		goto done;
 	}
 
-#ifdef ICE_LSE_SPT
-	if (int_fw_ctl & PFINT_FW_CTL_INTEVENT_M) {
-		PMD_DRV_LOG(INFO, "FW_CTL: link state change event");
-		ice_handle_aq_msg(dev);
-	}
-#else
-	if (oicr & PFINT_OICR_LINK_STAT_CHANGE_M) {
-		PMD_DRV_LOG(INFO, "OICR: link state change event");
-		ret = ice_link_update(dev, 0);
-		if (!ret)
-			rte_eth_dev_callback_process
-				(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
-	}
-#endif
+	/* Always drain the AdminQ on any misc interrupt. */
+	ice_handle_aq_msg(dev);
 
 	if (oicr & PFINT_OICR_MAL_DETECT_M) {
 		PMD_DRV_LOG(WARNING, "OICR: MDD event");
@@ -1581,7 +1559,10 @@ ice_interrupt_handler(void *param)
 done:
 	/* Enable interrupt */
 	ice_pf_enable_irq0(hw);
-	rte_intr_ack(dev->intr_handle);
+	rte_intr_ack(pci_dev->intr_handle);
+
+	/* Re-drain AdminQ to catch events that arrived during the CLEARPBA window */
+	ice_handle_aq_msg(dev);
 }
 
 static void
@@ -4393,6 +4374,7 @@ ice_dev_start(struct rte_eth_dev *dev)
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct ice_vsi *vsi = pf->main_vsi;
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	struct ice_adapter *ad =
 			ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	uint16_t nb_rxq = 0;
@@ -4443,6 +4425,8 @@ ice_dev_start(struct rte_eth_dev *dev)
 	if (ice_rxq_intr_setup(dev))
 		return -EIO;
 
+	rte_intr_enable(pci_dev->intr_handle);
+
 	/* Enable receiving broadcast packets and transmitting packets */
 	ice_set_bit(ICE_PROMISC_BCAST_RX, pmask);
 	ice_set_bit(ICE_PROMISC_BCAST_TX, pmask);
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 0/2] net/ice: get link status updates via adminq message
  2026-02-27 11:02 [PATCH] net/ice: get link status updates via adminq message Bruce Richardson
  2026-02-27 11:41 ` [PATCH v2] " Bruce Richardson
@ 2026-03-02 11:48 ` Bruce Richardson
  2026-03-02 11:48   ` [PATCH v3 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
  2026-03-02 11:48   ` [PATCH v3 2/2] net/ice: get link status updates via adminq message Bruce Richardson
  2026-03-03 16:21 ` [PATCH v4 0/2] " Bruce Richardson
  2 siblings, 2 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-03-02 11:48 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson

As explained in patch 2, change the link status tracking to be via receipt
of an adminq message rather than directly querying the link status on
interrupt. As part of this change, we can reduce the cost of using the
adminq by removing the need to allocate and free memory but instead just
use the stack to store any received adminq messages.

V3: added patch 1 to reduce cost of querying the adminq.

v2: rebase on next-net-intel

Bruce Richardson (2):
  net/ice: remove malloc call for admin queue msg
  net/ice: get link status updates via adminq message

 drivers/net/intel/ice/ice_ethdev.c | 62 ++++++++++--------------------
 1 file changed, 21 insertions(+), 41 deletions(-)

--
2.51.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v3 1/2] net/ice: remove malloc call for admin queue msg
  2026-03-02 11:48 ` [PATCH v3 0/2] " Bruce Richardson
@ 2026-03-02 11:48   ` Bruce Richardson
  2026-03-02 11:48   ` [PATCH v3 2/2] net/ice: get link status updates via adminq message Bruce Richardson
  1 sibling, 0 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-03-02 11:48 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Anatoly Burakov

The max message size is defined as 4k, so we don't need a special
malloc/free (and especially not rte_malloc/rte_free) for each call into
the function - especially if no data is present. Replace the malloc
calls with a local memory buffer instead.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 0d6b030536..a59ca2e047 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -1440,17 +1440,14 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ice_ctl_q_info *cq = &hw->adminq;
-	struct ice_rq_event_info event;
+	unsigned char buf[ICE_AQ_MAX_BUF_LEN] = {0};
+	struct ice_rq_event_info event = {
+		.msg_buf = buf,
+		.buf_len = sizeof(buf),
+	};
 	uint16_t pending, opcode;
 	int ret;
 
-	event.buf_len = ICE_AQ_MAX_BUF_LEN;
-	event.msg_buf = rte_zmalloc(NULL, event.buf_len, 0);
-	if (!event.msg_buf) {
-		PMD_DRV_LOG(ERR, "Failed to allocate mem");
-		return;
-	}
-
 	pending = 1;
 	while (pending) {
 		ret = ice_clean_rq_elem(hw, cq, &event, &pending);
@@ -1477,7 +1474,6 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 			break;
 		}
 	}
-	rte_free(event.msg_buf);
 }
 #endif
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 2/2] net/ice: get link status updates via adminq message
  2026-03-02 11:48 ` [PATCH v3 0/2] " Bruce Richardson
  2026-03-02 11:48   ` [PATCH v3 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
@ 2026-03-02 11:48   ` Bruce Richardson
  1 sibling, 0 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-03-02 11:48 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Anatoly Burakov

Rather than relying directly on an interrupt we get link status updates
from the device firmware via adminq messages.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c | 48 ++++++++++--------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index a59ca2e047..8286816f06 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -1397,7 +1397,9 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA, 0);
 	ICE_READ_REG(hw, PFINT_OICR);
 
-#ifdef ICE_LSE_SPT
+	/* Enable all OICR causes except link-state-change: LSC is delivered
+	 * as an unsolicited AdminQ get-link-status notification.
+	 */
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA,
 		      (uint32_t)(PFINT_OICR_ENA_INT_ENA_M &
 				 (~PFINT_OICR_LINK_STAT_CHANGE_M)));
@@ -1413,9 +1415,6 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 		      ((0 << PFINT_FW_CTL_ITR_INDX_S) &
 		       PFINT_FW_CTL_ITR_INDX_M) |
 		      PFINT_FW_CTL_CAUSE_ENA_M);
-#else
-	ICE_WRITE_REG(hw, PFINT_OICR_ENA, PFINT_OICR_ENA_INT_ENA_M);
-#endif
 
 	ICE_WRITE_REG(hw, GLINT_DYN_CTL(0),
 		      GLINT_DYN_CTL_INTENA_M |
@@ -1434,7 +1433,6 @@ ice_pf_disable_irq0(struct ice_hw *hw)
 	ice_flush(hw);
 }
 
-#ifdef ICE_LSE_SPT
 static void
 ice_handle_aq_msg(struct rte_eth_dev *dev)
 {
@@ -1453,10 +1451,9 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		ret = ice_clean_rq_elem(hw, cq, &event, &pending);
 
 		if (ret != ICE_SUCCESS) {
-			PMD_DRV_LOG(INFO,
-				    "Failed to read msg from AdminQ, "
-				    "adminq_err: %u",
-				    hw->adminq.sq_last_status);
+			if (hw->adminq.sq_last_status != 0)
+				PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ, adminq_err: %u",
+						hw->adminq.sq_last_status);
 			break;
 		}
 		opcode = rte_le_to_cpu_16(event.desc.opcode);
@@ -1475,7 +1472,6 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		}
 	}
 }
-#endif
 
 /**
  * Interrupt handler triggered by NIC for handling
@@ -1494,24 +1490,18 @@ ice_interrupt_handler(void *param)
 {
 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	uint32_t oicr;
 	uint32_t reg;
 	uint8_t pf_num;
 	uint8_t event;
 	uint16_t queue;
-	int ret;
-#ifdef ICE_LSE_SPT
-	uint32_t int_fw_ctl;
-#endif
 
 	/* Disable interrupt */
 	ice_pf_disable_irq0(hw);
 
 	/* read out interrupt causes */
 	oicr = ICE_READ_REG(hw, PFINT_OICR);
-#ifdef ICE_LSE_SPT
-	int_fw_ctl = ICE_READ_REG(hw, PFINT_FW_CTL);
-#endif
 
 	/* No interrupt event indicated */
 	if (!(oicr & PFINT_OICR_INTEVENT_M)) {
@@ -1519,20 +1509,8 @@ ice_interrupt_handler(void *param)
 		goto done;
 	}
 
-#ifdef ICE_LSE_SPT
-	if (int_fw_ctl & PFINT_FW_CTL_INTEVENT_M) {
-		PMD_DRV_LOG(INFO, "FW_CTL: link state change event");
-		ice_handle_aq_msg(dev);
-	}
-#else
-	if (oicr & PFINT_OICR_LINK_STAT_CHANGE_M) {
-		PMD_DRV_LOG(INFO, "OICR: link state change event");
-		ret = ice_link_update(dev, 0);
-		if (!ret)
-			rte_eth_dev_callback_process
-				(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
-	}
-#endif
+	/* Always drain the AdminQ on any misc interrupt. */
+	ice_handle_aq_msg(dev);
 
 	if (oicr & PFINT_OICR_MAL_DETECT_M) {
 		PMD_DRV_LOG(WARNING, "OICR: MDD event");
@@ -1581,7 +1559,10 @@ ice_interrupt_handler(void *param)
 done:
 	/* Enable interrupt */
 	ice_pf_enable_irq0(hw);
-	rte_intr_ack(dev->intr_handle);
+	rte_intr_ack(pci_dev->intr_handle);
+
+	/* Re-drain AdminQ to catch events that arrived during the CLEARPBA window */
+	ice_handle_aq_msg(dev);
 }
 
 static void
@@ -4393,6 +4374,7 @@ ice_dev_start(struct rte_eth_dev *dev)
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct ice_vsi *vsi = pf->main_vsi;
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	struct ice_adapter *ad =
 			ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	uint16_t nb_rxq = 0;
@@ -4443,6 +4425,8 @@ ice_dev_start(struct rte_eth_dev *dev)
 	if (ice_rxq_intr_setup(dev))
 		return -EIO;
 
+	rte_intr_enable(pci_dev->intr_handle);
+
 	/* Enable receiving broadcast packets and transmitting packets */
 	ice_set_bit(ICE_PROMISC_BCAST_RX, pmask);
 	ice_set_bit(ICE_PROMISC_BCAST_TX, pmask);
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 0/2] net/ice: get link status updates via adminq message
  2026-02-27 11:02 [PATCH] net/ice: get link status updates via adminq message Bruce Richardson
  2026-02-27 11:41 ` [PATCH v2] " Bruce Richardson
  2026-03-02 11:48 ` [PATCH v3 0/2] " Bruce Richardson
@ 2026-03-03 16:21 ` Bruce Richardson
  2026-03-03 16:21   ` [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
                     ` (3 more replies)
  2 siblings, 4 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-03-03 16:21 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson

As explained in patch 2, change the link status tracking to be via receipt
of an adminq message rather than directly querying the link status on
interrupt. As part of this change, we can reduce the cost of using the
adminq by removing the need to allocate and free memory but instead just
use the stack to store any received adminq messages.

V4: resubmit to recheck in CI, now that next-net-intel tree is clean

V3: added patch 1 to reduce cost of querying the adminq.

v2: rebase on next-net-intel

Bruce Richardson (2):
  net/ice: remove malloc call for admin queue msg
  net/ice: get link status updates via adminq message

 drivers/net/intel/ice/ice_ethdev.c | 62 ++++++++++--------------------
 1 file changed, 21 insertions(+), 41 deletions(-)

--
2.51.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg
  2026-03-03 16:21 ` [PATCH v4 0/2] " Bruce Richardson
@ 2026-03-03 16:21   ` Bruce Richardson
  2026-03-04 11:59     ` Loftus, Ciara
  2026-03-03 16:21   ` [PATCH v4 2/2] net/ice: get link status updates via adminq message Bruce Richardson
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Bruce Richardson @ 2026-03-03 16:21 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson

The max message size is defined as 4k, so we don't need a special
malloc/free (and especially not rte_malloc/rte_free) for each call into
the function - especially if no data is present. Replace the malloc
calls with a local memory buffer instead.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 0d6b030536..a59ca2e047 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -1440,17 +1440,14 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 {
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ice_ctl_q_info *cq = &hw->adminq;
-	struct ice_rq_event_info event;
+	unsigned char buf[ICE_AQ_MAX_BUF_LEN] = {0};
+	struct ice_rq_event_info event = {
+		.msg_buf = buf,
+		.buf_len = sizeof(buf),
+	};
 	uint16_t pending, opcode;
 	int ret;

-	event.buf_len = ICE_AQ_MAX_BUF_LEN;
-	event.msg_buf = rte_zmalloc(NULL, event.buf_len, 0);
-	if (!event.msg_buf) {
-		PMD_DRV_LOG(ERR, "Failed to allocate mem");
-		return;
-	}
-
 	pending = 1;
 	while (pending) {
 		ret = ice_clean_rq_elem(hw, cq, &event, &pending);
@@ -1477,7 +1474,6 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 			break;
 		}
 	}
-	rte_free(event.msg_buf);
 }
 #endif

--
2.51.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 2/2] net/ice: get link status updates via adminq message
  2026-03-03 16:21 ` [PATCH v4 0/2] " Bruce Richardson
  2026-03-03 16:21   ` [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
@ 2026-03-03 16:21   ` Bruce Richardson
  2026-03-04 11:56     ` Loftus, Ciara
  2026-03-04  9:58   ` [PATCH v4 0/2] " Bruce Richardson
  2026-03-05 12:53   ` David Marchand
  3 siblings, 1 reply; 13+ messages in thread
From: Bruce Richardson @ 2026-03-03 16:21 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson

Rather than relying directly on an interrupt we get link status updates
from the device firmware via adminq messages.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c | 48 ++++++++++--------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index a59ca2e047..8286816f06 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -1397,7 +1397,9 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA, 0);
 	ICE_READ_REG(hw, PFINT_OICR);

-#ifdef ICE_LSE_SPT
+	/* Enable all OICR causes except link-state-change: LSC is delivered
+	 * as an unsolicited AdminQ get-link-status notification.
+	 */
 	ICE_WRITE_REG(hw, PFINT_OICR_ENA,
 		      (uint32_t)(PFINT_OICR_ENA_INT_ENA_M &
 				 (~PFINT_OICR_LINK_STAT_CHANGE_M)));
@@ -1413,9 +1415,6 @@ ice_pf_enable_irq0(struct ice_hw *hw)
 		      ((0 << PFINT_FW_CTL_ITR_INDX_S) &
 		       PFINT_FW_CTL_ITR_INDX_M) |
 		      PFINT_FW_CTL_CAUSE_ENA_M);
-#else
-	ICE_WRITE_REG(hw, PFINT_OICR_ENA, PFINT_OICR_ENA_INT_ENA_M);
-#endif

 	ICE_WRITE_REG(hw, GLINT_DYN_CTL(0),
 		      GLINT_DYN_CTL_INTENA_M |
@@ -1434,7 +1433,6 @@ ice_pf_disable_irq0(struct ice_hw *hw)
 	ice_flush(hw);
 }

-#ifdef ICE_LSE_SPT
 static void
 ice_handle_aq_msg(struct rte_eth_dev *dev)
 {
@@ -1453,10 +1451,9 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		ret = ice_clean_rq_elem(hw, cq, &event, &pending);

 		if (ret != ICE_SUCCESS) {
-			PMD_DRV_LOG(INFO,
-				    "Failed to read msg from AdminQ, "
-				    "adminq_err: %u",
-				    hw->adminq.sq_last_status);
+			if (hw->adminq.sq_last_status != 0)
+				PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ, adminq_err: %u",
+						hw->adminq.sq_last_status);
 			break;
 		}
 		opcode = rte_le_to_cpu_16(event.desc.opcode);
@@ -1475,7 +1472,6 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
 		}
 	}
 }
-#endif

 /**
  * Interrupt handler triggered by NIC for handling
@@ -1494,24 +1490,18 @@ ice_interrupt_handler(void *param)
 {
 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	uint32_t oicr;
 	uint32_t reg;
 	uint8_t pf_num;
 	uint8_t event;
 	uint16_t queue;
-	int ret;
-#ifdef ICE_LSE_SPT
-	uint32_t int_fw_ctl;
-#endif

 	/* Disable interrupt */
 	ice_pf_disable_irq0(hw);

 	/* read out interrupt causes */
 	oicr = ICE_READ_REG(hw, PFINT_OICR);
-#ifdef ICE_LSE_SPT
-	int_fw_ctl = ICE_READ_REG(hw, PFINT_FW_CTL);
-#endif

 	/* No interrupt event indicated */
 	if (!(oicr & PFINT_OICR_INTEVENT_M)) {
@@ -1519,20 +1509,8 @@ ice_interrupt_handler(void *param)
 		goto done;
 	}

-#ifdef ICE_LSE_SPT
-	if (int_fw_ctl & PFINT_FW_CTL_INTEVENT_M) {
-		PMD_DRV_LOG(INFO, "FW_CTL: link state change event");
-		ice_handle_aq_msg(dev);
-	}
-#else
-	if (oicr & PFINT_OICR_LINK_STAT_CHANGE_M) {
-		PMD_DRV_LOG(INFO, "OICR: link state change event");
-		ret = ice_link_update(dev, 0);
-		if (!ret)
-			rte_eth_dev_callback_process
-				(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
-	}
-#endif
+	/* Always drain the AdminQ on any misc interrupt. */
+	ice_handle_aq_msg(dev);

 	if (oicr & PFINT_OICR_MAL_DETECT_M) {
 		PMD_DRV_LOG(WARNING, "OICR: MDD event");
@@ -1581,7 +1559,10 @@ ice_interrupt_handler(void *param)
 done:
 	/* Enable interrupt */
 	ice_pf_enable_irq0(hw);
-	rte_intr_ack(dev->intr_handle);
+	rte_intr_ack(pci_dev->intr_handle);
+
+	/* Re-drain AdminQ to catch events that arrived during the CLEARPBA window */
+	ice_handle_aq_msg(dev);
 }

 static void
@@ -4393,6 +4374,7 @@ ice_dev_start(struct rte_eth_dev *dev)
 	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct ice_vsi *vsi = pf->main_vsi;
+	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
 	struct ice_adapter *ad =
 			ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	uint16_t nb_rxq = 0;
@@ -4443,6 +4425,8 @@ ice_dev_start(struct rte_eth_dev *dev)
 	if (ice_rxq_intr_setup(dev))
 		return -EIO;

+	rte_intr_enable(pci_dev->intr_handle);
+
 	/* Enable receiving broadcast packets and transmitting packets */
 	ice_set_bit(ICE_PROMISC_BCAST_RX, pmask);
 	ice_set_bit(ICE_PROMISC_BCAST_TX, pmask);
--
2.51.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 0/2] net/ice: get link status updates via adminq message
  2026-03-03 16:21 ` [PATCH v4 0/2] " Bruce Richardson
  2026-03-03 16:21   ` [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
  2026-03-03 16:21   ` [PATCH v4 2/2] net/ice: get link status updates via adminq message Bruce Richardson
@ 2026-03-04  9:58   ` Bruce Richardson
  2026-03-05 12:53   ` David Marchand
  3 siblings, 0 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-03-04  9:58 UTC (permalink / raw)
  To: dev

On Tue, Mar 03, 2026 at 04:21:55PM +0000, Bruce Richardson wrote:
> As explained in patch 2, change the link status tracking to be via receipt
> of an adminq message rather than directly querying the link status on
> interrupt. As part of this change, we can reduce the cost of using the
> adminq by removing the need to allocate and free memory but instead just
> use the stack to store any received adminq messages.
> 
Recheck-request: loongarch-unit-testing

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH v4 2/2] net/ice: get link status updates via adminq message
  2026-03-03 16:21   ` [PATCH v4 2/2] net/ice: get link status updates via adminq message Bruce Richardson
@ 2026-03-04 11:56     ` Loftus, Ciara
  0 siblings, 0 replies; 13+ messages in thread
From: Loftus, Ciara @ 2026-03-04 11:56 UTC (permalink / raw)
  To: Richardson, Bruce, dev@dpdk.org; +Cc: Richardson, Bruce

> Subject: [PATCH v4 2/2] net/ice: get link status updates via adminq message
> 
> Rather than relying directly on an interrupt we get link status updates
> from the device firmware via adminq messages.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
>  drivers/net/intel/ice/ice_ethdev.c | 48 ++++++++++--------------------
>  1 file changed, 16 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/net/intel/ice/ice_ethdev.c
> b/drivers/net/intel/ice/ice_ethdev.c
> index a59ca2e047..8286816f06 100644
> --- a/drivers/net/intel/ice/ice_ethdev.c
> +++ b/drivers/net/intel/ice/ice_ethdev.c

snip

> 
>  static void
> @@ -4393,6 +4374,7 @@ ice_dev_start(struct rte_eth_dev *dev)
>  	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
>  	struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
>  	struct ice_vsi *vsi = pf->main_vsi;
> +	struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
>  	struct ice_adapter *ad =
>  			ICE_DEV_PRIVATE_TO_ADAPTER(dev->data-
> >dev_private);
>  	uint16_t nb_rxq = 0;
> @@ -4443,6 +4425,8 @@ ice_dev_start(struct rte_eth_dev *dev)
>  	if (ice_rxq_intr_setup(dev))
>  		return -EIO;
> 
> +	rte_intr_enable(pci_dev->intr_handle);

Looks good to me.
I simulated link up/down and verified that the adminq messages were received as expected.

I'm wondering if the call to rte_intr_enable is needed here? It's already called in ice_rxq_intr_setup.

Other than that LGTM.

Acked-by: Ciara Loftus <ciara.loftus@intel.com>

> +
>  	/* Enable receiving broadcast packets and transmitting packets */
>  	ice_set_bit(ICE_PROMISC_BCAST_RX, pmask);
>  	ice_set_bit(ICE_PROMISC_BCAST_TX, pmask);
> --
> 2.51.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg
  2026-03-03 16:21   ` [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
@ 2026-03-04 11:59     ` Loftus, Ciara
  0 siblings, 0 replies; 13+ messages in thread
From: Loftus, Ciara @ 2026-03-04 11:59 UTC (permalink / raw)
  To: Richardson, Bruce, dev@dpdk.org; +Cc: Richardson, Bruce

> Subject: [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg
> 
> The max message size is defined as 4k, so we don't need a special
> malloc/free (and especially not rte_malloc/rte_free) for each call into
> the function - especially if no data is present. Replace the malloc
> calls with a local memory buffer instead.
> 
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>

Acked-by: Ciara Loftus <ciara.loftus@intel.com>

> ---
>  drivers/net/intel/ice/ice_ethdev.c | 14 +++++---------
>  1 file changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/intel/ice/ice_ethdev.c
> b/drivers/net/intel/ice/ice_ethdev.c
> index 0d6b030536..a59ca2e047 100644
> --- a/drivers/net/intel/ice/ice_ethdev.c
> +++ b/drivers/net/intel/ice/ice_ethdev.c
> @@ -1440,17 +1440,14 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
>  {
>  	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
>  	struct ice_ctl_q_info *cq = &hw->adminq;
> -	struct ice_rq_event_info event;
> +	unsigned char buf[ICE_AQ_MAX_BUF_LEN] = {0};
> +	struct ice_rq_event_info event = {
> +		.msg_buf = buf,
> +		.buf_len = sizeof(buf),
> +	};
>  	uint16_t pending, opcode;
>  	int ret;
> 
> -	event.buf_len = ICE_AQ_MAX_BUF_LEN;
> -	event.msg_buf = rte_zmalloc(NULL, event.buf_len, 0);
> -	if (!event.msg_buf) {
> -		PMD_DRV_LOG(ERR, "Failed to allocate mem");
> -		return;
> -	}
> -
>  	pending = 1;
>  	while (pending) {
>  		ret = ice_clean_rq_elem(hw, cq, &event, &pending);
> @@ -1477,7 +1474,6 @@ ice_handle_aq_msg(struct rte_eth_dev *dev)
>  			break;
>  		}
>  	}
> -	rte_free(event.msg_buf);
>  }
>  #endif
> 
> --
> 2.51.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 0/2] net/ice: get link status updates via adminq message
  2026-03-03 16:21 ` [PATCH v4 0/2] " Bruce Richardson
                     ` (2 preceding siblings ...)
  2026-03-04  9:58   ` [PATCH v4 0/2] " Bruce Richardson
@ 2026-03-05 12:53   ` David Marchand
  2026-03-05 15:15     ` Bruce Richardson
  3 siblings, 1 reply; 13+ messages in thread
From: David Marchand @ 2026-03-05 12:53 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev

On Tue, 3 Mar 2026 at 17:22, Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> As explained in patch 2, change the link status tracking to be via receipt
> of an adminq message rather than directly querying the link status on
> interrupt. As part of this change, we can reduce the cost of using the
> adminq by removing the need to allocate and free memory but instead just
> use the stack to store any received adminq messages.
>
> V4: resubmit to recheck in CI, now that next-net-intel tree is clean
>
> V3: added patch 1 to reduce cost of querying the adminq.
>
> v2: rebase on next-net-intel
>
> Bruce Richardson (2):
>   net/ice: remove malloc call for admin queue msg
>   net/ice: get link status updates via adminq message
>
>  drivers/net/intel/ice/ice_ethdev.c | 62 ++++++++++--------------------
>  1 file changed, 21 insertions(+), 41 deletions(-)

Did a quick test with 2 E810 25G ports connected to another E810, with
and without LSC interrupt in testpmd, and in OVS.
Those ports link status gets updated quickly in all scenarios.
I did not test on a long duration, nor with other types of interrupts
in the mix.

For the series,
Tested-by: David Marchand <david.marchand@redhat.com>


-- 
David Marchand


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 0/2] net/ice: get link status updates via adminq message
  2026-03-05 12:53   ` David Marchand
@ 2026-03-05 15:15     ` Bruce Richardson
  0 siblings, 0 replies; 13+ messages in thread
From: Bruce Richardson @ 2026-03-05 15:15 UTC (permalink / raw)
  To: David Marchand; +Cc: dev

On Thu, Mar 05, 2026 at 01:53:25PM +0100, David Marchand wrote:
> On Tue, 3 Mar 2026 at 17:22, Bruce Richardson
> <bruce.richardson@intel.com> wrote:
> >
> > As explained in patch 2, change the link status tracking to be via receipt
> > of an adminq message rather than directly querying the link status on
> > interrupt. As part of this change, we can reduce the cost of using the
> > adminq by removing the need to allocate and free memory but instead just
> > use the stack to store any received adminq messages.
> >
> > V4: resubmit to recheck in CI, now that next-net-intel tree is clean
> >
> > V3: added patch 1 to reduce cost of querying the adminq.
> >
> > v2: rebase on next-net-intel
> >
> > Bruce Richardson (2):
> >   net/ice: remove malloc call for admin queue msg
> >   net/ice: get link status updates via adminq message
> >
> >  drivers/net/intel/ice/ice_ethdev.c | 62 ++++++++++--------------------
> >  1 file changed, 21 insertions(+), 41 deletions(-)
> 
> Did a quick test with 2 E810 25G ports connected to another E810, with
> and without LSC interrupt in testpmd, and in OVS.
> Those ports link status gets updated quickly in all scenarios.
> I did not test on a long duration, nor with other types of interrupts
> in the mix.
> 
> For the series,
> Tested-by: David Marchand <david.marchand@redhat.com>
> 
Series applied to dpdk-next-net-intel.

/Bruce

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-03-05 15:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-27 11:02 [PATCH] net/ice: get link status updates via adminq message Bruce Richardson
2026-02-27 11:41 ` [PATCH v2] " Bruce Richardson
2026-03-02 11:48 ` [PATCH v3 0/2] " Bruce Richardson
2026-03-02 11:48   ` [PATCH v3 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
2026-03-02 11:48   ` [PATCH v3 2/2] net/ice: get link status updates via adminq message Bruce Richardson
2026-03-03 16:21 ` [PATCH v4 0/2] " Bruce Richardson
2026-03-03 16:21   ` [PATCH v4 1/2] net/ice: remove malloc call for admin queue msg Bruce Richardson
2026-03-04 11:59     ` Loftus, Ciara
2026-03-03 16:21   ` [PATCH v4 2/2] net/ice: get link status updates via adminq message Bruce Richardson
2026-03-04 11:56     ` Loftus, Ciara
2026-03-04  9:58   ` [PATCH v4 0/2] " Bruce Richardson
2026-03-05 12:53   ` David Marchand
2026-03-05 15:15     ` Bruce Richardson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox