patch 'net/iavf: reuse device alarm for PHC sync' has been queued to stable release 25.11.3

Kevin Traynor ktraynor at redhat.com
Thu Jul 23 19:15:19 CEST 2026


Hi,

FYI, your patch has been queued to stable release 25.11.3

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 07/27/26. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/8cfa9c09e88dcb968377f3a12fc37c431b80fc8e

Thanks.

Kevin

---
>From 8cfa9c09e88dcb968377f3a12fc37c431b80fc8e Mon Sep 17 00:00:00 2001
From: Soumyadeep Hore <soumyadeep.hore at intel.com>
Date: Wed, 20 May 2026 14:43:49 -0400
Subject: [PATCH] net/iavf: reuse device alarm for PHC sync

[ upstream commit 388f0b34806536c942a36845011ae77ad4095055 ]

Reuse existing iavf device alarm cadence to drive periodic PHC sync
instead of a dedicated PHC alarm callback.

Keep PHC start/stop hooks as pause/resume controls around queue
reconfiguration and device lifecycle paths, including WB_ON_ITR mode.

Refresh PHC state from the first active RX queue and propagate it to
all active RX queues so per-queue timestamp conversion stays aligned.

Bugzilla ID: 1898
Fixes: 61b6874b9224 ("net/iavf: support Rx timestamp offload on AVX512")
Fixes: 6ad2944f4e82 ("net/iavf: support Rx timestamp offload on AVX2")
Fixes: 33db16136e55 ("net/iavf: improve performance of Rx timestamp offload")

Signed-off-by: Soumyadeep Hore <soumyadeep.hore at intel.com>
Acked-by: Bruce Richardson <bruce.richardson at intel.com>
---
 drivers/net/intel/iavf/iavf.h        |   6 +
 drivers/net/intel/iavf/iavf_ethdev.c | 168 ++++++++++++++++++++++++---
 drivers/net/intel/iavf/iavf_vchnl.c  |   4 +
 3 files changed, 164 insertions(+), 14 deletions(-)

diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
index 3cb2fd0602..a78ab020ba 100644
--- a/drivers/net/intel/iavf/iavf.h
+++ b/drivers/net/intel/iavf/iavf.h
@@ -76,4 +76,5 @@
 
 #define IAVF_ALARM_INTERVAL 50000 /* us */
+#define IAVF_PHC_SYNC_ALARM_INTERVAL_US 200000
 
 /* The overhead from MTU to max frame size.
@@ -385,4 +386,7 @@ struct iavf_adapter {
 	enum iavf_tx_func_type tx_func_type;
 	uint16_t fdir_ref_cnt;
+	rte_spinlock_t phc_sync_lock;
+	uint8_t phc_sync_ticks;
+	bool phc_sync_paused;
 	struct iavf_devargs devargs;
 	bool mac_primary_set;
@@ -521,4 +525,6 @@ int iavf_dev_link_update(struct rte_eth_dev *dev,
 			__rte_unused int wait_to_complete);
 void iavf_dev_alarm_handler(void *param);
+void iavf_phc_sync_alarm_start(struct rte_eth_dev *dev);
+void iavf_phc_sync_alarm_stop(struct rte_eth_dev *dev);
 int iavf_query_stats(struct iavf_adapter *adapter,
 		    struct virtchnl_eth_stats **pstats);
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index c604563be4..4e24a37b47 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -22,4 +22,5 @@
 #include <rte_alarm.h>
 #include <rte_atomic.h>
+#include <rte_cycles.h>
 #include <rte_eal.h>
 #include <rte_ether.h>
@@ -146,4 +147,10 @@ static int iavf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
 static void iavf_dev_interrupt_handler(void *param);
 static void iavf_disable_irq0(struct iavf_hw *hw);
+static struct ci_rx_queue *iavf_phc_sync_rxq_get(struct rte_eth_dev *dev);
+static void iavf_phc_sync_update_all_rxq(struct rte_eth_dev *dev,
+					 uint64_t phc_time,
+					 uint64_t sw_cur_time);
+static bool iavf_phc_sync_alarm_needed(struct rte_eth_dev *dev);
+static void iavf_phc_sync_tick(struct rte_eth_dev *dev);
 static int iavf_dev_flow_ops_get(struct rte_eth_dev *dev,
 				 const struct rte_flow_ops **ops);
@@ -1085,4 +1092,6 @@ iavf_dev_start(struct rte_eth_dev *dev)
 	}
 
+	iavf_phc_sync_alarm_start(dev);
+
 	return 0;
 
@@ -1111,4 +1120,6 @@ iavf_dev_stop(struct rte_eth_dev *dev)
 		return 0;
 
+	iavf_phc_sync_alarm_stop(dev);
+
 	/* Disable the interrupt for Rx */
 	rte_intr_efd_disable(intr_handle);
@@ -2730,25 +2741,101 @@ iavf_dev_interrupt_handler(void *param)
 }
 
+static struct ci_rx_queue *
+iavf_phc_sync_rxq_get(struct rte_eth_dev *dev)
+{
+	struct ci_rx_queue *rxq;
+	uint16_t i;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (rxq != NULL)
+			return rxq;
+	}
+
+	return NULL;
+}
+
+static void
+iavf_phc_sync_update_all_rxq(struct rte_eth_dev *dev,
+			     uint64_t phc_time,
+			     uint64_t sw_cur_time)
+{
+	struct ci_rx_queue *rxq;
+	uint16_t i;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (rxq == NULL)
+			continue;
+
+		rxq->phc_time = phc_time;
+		rxq->hw_time_update = sw_cur_time;
+	}
+}
+
+static void
+iavf_phc_sync_tick(struct rte_eth_dev *dev)
+{
+	struct iavf_adapter *adapter;
+	const uint16_t phc_sync_ticks_max = RTE_MAX((uint16_t)1,
+		(uint16_t)(IAVF_PHC_SYNC_ALARM_INTERVAL_US / IAVF_ALARM_INTERVAL));
+	struct ci_rx_queue *sync_rxq;
+	uint64_t sw_cur_time;
+
+	adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	rte_spinlock_lock(&adapter->phc_sync_lock);
+	if (adapter->phc_sync_paused || !iavf_phc_sync_alarm_needed(dev)) {
+		adapter->phc_sync_ticks = 0;
+		goto unlock;
+	}
+
+	if (++adapter->phc_sync_ticks < phc_sync_ticks_max)
+		goto unlock;
+
+	adapter->phc_sync_ticks = 0;
+	sync_rxq = iavf_phc_sync_rxq_get(dev);
+	if (sync_rxq == NULL)
+		goto unlock;
+
+	if (iavf_get_phc_time(sync_rxq) != 0) {
+		PMD_DRV_LOG(ERR, "get physical time failed");
+		goto unlock;
+	}
+
+	sw_cur_time = rte_get_timer_cycles() / (rte_get_timer_hz() / 1000);
+	iavf_phc_sync_update_all_rxq(dev, sync_rxq->phc_time, sw_cur_time);
+
+unlock:
+	rte_spinlock_unlock(&adapter->phc_sync_lock);
+}
+
 void
 iavf_dev_alarm_handler(void *param)
 {
 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+	struct iavf_info *vf;
 	if (dev == NULL || dev->data == NULL || dev->data->dev_private == NULL)
 		return;
 
+	vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint32_t icr0;
 
-	iavf_disable_irq0(hw);
+	if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)) {
+		iavf_disable_irq0(hw);
 
-	/* read out interrupt causes */
-	icr0 = IAVF_READ_REG(hw, IAVF_VFINT_ICR01);
+		/* read out interrupt causes */
+		icr0 = IAVF_READ_REG(hw, IAVF_VFINT_ICR01);
 
-	if (icr0 & IAVF_VFINT_ICR01_ADMINQ_MASK) {
-		PMD_DRV_LOG(DEBUG, "ICR01_ADMINQ is reported");
-		iavf_handle_virtchnl_msg(dev);
+		if (icr0 & IAVF_VFINT_ICR01_ADMINQ_MASK) {
+			PMD_DRV_LOG(DEBUG, "ICR01_ADMINQ is reported");
+			iavf_handle_virtchnl_msg(dev);
+		}
+
+		iavf_enable_irq0(hw);
 	}
 
-	iavf_enable_irq0(hw);
+	iavf_phc_sync_tick(dev);
 
 	rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
@@ -2756,4 +2843,56 @@ iavf_dev_alarm_handler(void *param)
 }
 
+static bool
+iavf_phc_sync_alarm_needed(struct rte_eth_dev *dev)
+{
+	struct iavf_adapter *adapter;
+
+	adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+
+	if (adapter->closed || adapter->stopped)
+		return false;
+
+	if (!(dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP))
+		return false;
+
+	if (dev->data->nb_rx_queues == 0)
+		return false;
+
+	if (iavf_phc_sync_rxq_get(dev) == NULL)
+		return false;
+
+	return true;
+}
+
+void
+iavf_phc_sync_alarm_start(struct rte_eth_dev *dev)
+{
+	struct iavf_adapter *adapter;
+
+	if (!iavf_phc_sync_alarm_needed(dev))
+		return;
+
+	adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	rte_spinlock_lock(&adapter->phc_sync_lock);
+	adapter->phc_sync_paused = false;
+	adapter->phc_sync_ticks = 0;
+	rte_spinlock_unlock(&adapter->phc_sync_lock);
+}
+
+void
+iavf_phc_sync_alarm_stop(struct rte_eth_dev *dev)
+{
+	struct iavf_adapter *adapter;
+
+	if (dev == NULL || dev->data == NULL || dev->data->dev_private == NULL)
+		return;
+
+	adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	rte_spinlock_lock(&adapter->phc_sync_lock);
+	adapter->phc_sync_paused = true;
+	adapter->phc_sync_ticks = 0;
+	rte_spinlock_unlock(&adapter->phc_sync_lock);
+}
+
 static int
 iavf_dev_flow_ops_get(struct rte_eth_dev *dev,
@@ -2833,4 +2972,5 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
 	adapter->stopped = 1;
 	adapter->mac_primary_set = false;
+	rte_spinlock_init(&adapter->phc_sync_lock);
 
 	if (iavf_dev_event_handler_init())
@@ -2872,7 +3012,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
 		/* enable uio intr after callback register */
 		rte_intr_enable(pci_dev->intr_handle);
-	else
-		rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
-				  iavf_dev_alarm_handler, eth_dev);
+
+	rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
+			  iavf_dev_alarm_handler, eth_dev);
 
 	/* configure and enable device interrupt */
@@ -2934,7 +3074,7 @@ flow_init_err:
 		rte_intr_callback_unregister(pci_dev->intr_handle,
 					     iavf_dev_interrupt_handler, eth_dev);
-	} else {
-		rte_eal_alarm_cancel(iavf_dev_alarm_handler, eth_dev);
 	}
+	iavf_phc_sync_alarm_stop(eth_dev);
+	rte_eal_alarm_cancel(iavf_dev_alarm_handler, eth_dev);
 
 	rte_free(eth_dev->data->mac_addrs);
@@ -3003,7 +3143,7 @@ iavf_dev_close(struct rte_eth_dev *dev)
 		rte_intr_callback_unregister(intr_handle,
 					     iavf_dev_interrupt_handler, dev);
-	} else {
-		rte_eal_alarm_cancel(iavf_dev_alarm_handler, dev);
 	}
+	iavf_phc_sync_alarm_stop(dev);
+	rte_eal_alarm_cancel(iavf_dev_alarm_handler, dev);
 	iavf_disable_irq0(hw);
 
diff --git a/drivers/net/intel/iavf/iavf_vchnl.c b/drivers/net/intel/iavf/iavf_vchnl.c
index 9ad39300c6..a6539fea4a 100644
--- a/drivers/net/intel/iavf/iavf_vchnl.c
+++ b/drivers/net/intel/iavf/iavf_vchnl.c
@@ -2092,10 +2092,14 @@ iavf_request_queues(struct rte_eth_dev *dev, uint16_t num)
 
 	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
+		iavf_phc_sync_alarm_stop(dev);
 		err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
+		iavf_phc_sync_alarm_start(dev);
 	} else {
+		iavf_phc_sync_alarm_stop(dev);
 		rte_eal_alarm_cancel(iavf_dev_alarm_handler, dev);
 		err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
 		rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
 				  iavf_dev_alarm_handler, dev);
+		iavf_phc_sync_alarm_start(dev);
 	}
 
-- 
2.55.0

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-07-23 17:58:00.274157430 +0100
+++ 0056-net-iavf-reuse-device-alarm-for-PHC-sync.patch	2026-07-23 17:57:58.671918573 +0100
@@ -1 +1 @@
-From 388f0b34806536c942a36845011ae77ad4095055 Mon Sep 17 00:00:00 2001
+From 8cfa9c09e88dcb968377f3a12fc37c431b80fc8e Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 388f0b34806536c942a36845011ae77ad4095055 ]
+
@@ -19 +20,0 @@
-Cc: stable at dpdk.org
@@ -30 +31 @@
-index 385dcd5c79..2615b6f034 100644
+index 3cb2fd0602..a78ab020ba 100644
@@ -33 +34 @@
-@@ -77,4 +77,5 @@
+@@ -76,4 +76,5 @@
@@ -39 +40 @@
-@@ -393,4 +394,7 @@ struct iavf_adapter {
+@@ -385,4 +386,7 @@ struct iavf_adapter {
@@ -47 +48 @@
-@@ -477,4 +481,6 @@ int iavf_dev_link_update(struct rte_eth_dev *dev,
+@@ -521,4 +525,6 @@ int iavf_dev_link_update(struct rte_eth_dev *dev,
@@ -53 +54 @@
- 		    struct virtchnl_eth_stats *pstats);
+ 		    struct virtchnl_eth_stats **pstats);
@@ -55 +56 @@
-index d3cb8ac16e..74771e3f9d 100644
+index c604563be4..4e24a37b47 100644
@@ -64 +65 @@
-@@ -152,4 +153,10 @@ static int iavf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
+@@ -146,4 +147,10 @@ static int iavf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
@@ -75 +76 @@
-@@ -1084,4 +1091,6 @@ iavf_dev_start(struct rte_eth_dev *dev)
+@@ -1085,4 +1092,6 @@ iavf_dev_start(struct rte_eth_dev *dev)
@@ -82 +83 @@
-@@ -1110,4 +1119,6 @@ iavf_dev_stop(struct rte_eth_dev *dev)
+@@ -1111,4 +1120,6 @@ iavf_dev_stop(struct rte_eth_dev *dev)
@@ -89 +90 @@
-@@ -2782,25 +2793,101 @@ iavf_dev_interrupt_handler(void *param)
+@@ -2730,25 +2741,101 @@ iavf_dev_interrupt_handler(void *param)
@@ -198 +199 @@
-@@ -2808,4 +2895,56 @@ iavf_dev_alarm_handler(void *param)
+@@ -2756,4 +2843,56 @@ iavf_dev_alarm_handler(void *param)
@@ -255 +256,2 @@
-@@ -2890,4 +3029,5 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
+@@ -2833,4 +2972,5 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
+ 	adapter->stopped = 1;
@@ -257 +258,0 @@
- 	adapter->tpid = RTE_ETHER_TYPE_VLAN; /* VLAN TPID set to 0x8100 by default */
@@ -261 +262 @@
-@@ -2929,7 +3069,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
+@@ -2872,7 +3012,7 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
@@ -272 +273 @@
-@@ -2993,7 +3133,7 @@ flow_init_err:
+@@ -2934,7 +3074,7 @@ flow_init_err:
@@ -282 +283 @@
-@@ -3066,7 +3206,7 @@ iavf_dev_close(struct rte_eth_dev *dev)
+@@ -3003,7 +3143,7 @@ iavf_dev_close(struct rte_eth_dev *dev)
@@ -293 +294 @@
-index 6dd7d455ba..66cbaca1cf 100644
+index 9ad39300c6..a6539fea4a 100644
@@ -296 +297 @@
-@@ -2317,10 +2317,14 @@ iavf_request_queues(struct rte_eth_dev *dev, uint16_t num)
+@@ -2092,10 +2092,14 @@ iavf_request_queues(struct rte_eth_dev *dev, uint16_t num)
@@ -300 +301 @@
- 		err = iavf_execute_vf_cmd_safe(adapter, &args);
+ 		err = iavf_execute_vf_cmd_safe(adapter, &args, 0);
@@ -305 +306 @@
- 		err = iavf_execute_vf_cmd_safe(adapter, &args);
+ 		err = iavf_execute_vf_cmd_safe(adapter, &args, 0);



More information about the stable mailing list