patch 'net/netvsc: switch data path to synthetic on device stop' has been queued to stable release 24.11.5
luca.boccassi at gmail.com
luca.boccassi at gmail.com
Thu Mar 26 13:57:55 CET 2026
Hi,
FYI, your patch has been queued to stable release 24.11.5
Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 03/28/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/bluca/dpdk-stable
This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/4a6b6e4150a3336cf40e9712bbf42a3278cab7e6
Thanks.
Luca Boccassi
---
>From 4a6b6e4150a3336cf40e9712bbf42a3278cab7e6 Mon Sep 17 00:00:00 2001
From: Long Li <longli at microsoft.com>
Date: Wed, 25 Mar 2026 11:57:50 -0700
Subject: [PATCH] net/netvsc: switch data path to synthetic on device stop
[ upstream commit da1fcd9b36d8d6e0dd87518ad675ccc61addf43f ]
When DPDK stops a netvsc device (e.g. on testpmd quit), the data path
was left pointing to the VF/MANA device. If the kernel netvsc driver
subsequently reloads the MANA device and opens it, incoming traffic
arrives on the MANA device immediately, before the queues are fully
initialized. This causes bogus RX completion events to appear on the
TX completion queue, triggering a kernel WARNING in mana_poll_tx_cq().
Fix this by switching the data path back to synthetic (via
NVS_DATAPATH_SYNTHETIC) in hn_vf_stop() before stopping the VF device.
This tells the host to route traffic through the synthetic path, so
that when the MANA driver recreates its queues, no unexpected traffic
arrives until netvsc explicitly switches back to VF.
Also update hn_vf_start() to switch the data path back to VF after the
VF device is started, enabling correct stop/start cycling.
Both functions now use write locks instead of read locks since they
modify vf_vsc_switched state.
Fixes: dc7680e8597c ("net/netvsc: support integrated VF")
Signed-off-by: Long Li <longli at microsoft.com>
---
drivers/net/netvsc/hn_vf.c | 65 ++++++++++++++++++++++++++++++++------
1 file changed, 55 insertions(+), 10 deletions(-)
diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c
index e9e52fbcfc..bcc61bf98c 100644
--- a/drivers/net/netvsc/hn_vf.c
+++ b/drivers/net/netvsc/hn_vf.c
@@ -318,9 +318,17 @@ int hn_vf_add_unlocked(struct rte_eth_dev *dev, struct hn_data *hv)
}
switch_data_path:
- ret = hn_nvs_set_datapath(hv, NVS_DATAPATH_VF);
- if (ret == 0)
- hv->vf_ctx.vf_vsc_switched = true;
+ /* Only switch data path to VF if the device is started.
+ * Otherwise defer to hn_vf_start() to avoid routing traffic
+ * to the VF before queues are set up.
+ */
+ if (dev->data->dev_started) {
+ ret = hn_nvs_set_datapath(hv, NVS_DATAPATH_VF);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Failed to switch to VF: %d", ret);
+ else
+ hv->vf_ctx.vf_vsc_switched = true;
+ }
exit:
return ret;
@@ -523,11 +531,31 @@ int hn_vf_start(struct rte_eth_dev *dev)
struct rte_eth_dev *vf_dev;
int ret = 0;
- rte_rwlock_read_lock(&hv->vf_lock);
+ rte_rwlock_write_lock(&hv->vf_lock);
vf_dev = hn_get_vf_dev(hv);
- if (vf_dev)
+ if (vf_dev) {
ret = rte_eth_dev_start(vf_dev->data->port_id);
- rte_rwlock_read_unlock(&hv->vf_lock);
+ if (ret == 0) {
+ /* Re-switch data path to VF if VSP has reported
+ * VF is present and we haven't switched yet
+ * (e.g. after a stop/start cycle).
+ */
+ if (hv->vf_ctx.vf_vsp_reported &&
+ !hv->vf_ctx.vf_vsc_switched) {
+ ret = hn_nvs_set_datapath(hv,
+ NVS_DATAPATH_VF);
+ if (ret) {
+ PMD_DRV_LOG(ERR,
+ "Failed to switch to VF: %d",
+ ret);
+ rte_eth_dev_stop(vf_dev->data->port_id);
+ } else {
+ hv->vf_ctx.vf_vsc_switched = true;
+ }
+ }
+ }
+ }
+ rte_rwlock_write_unlock(&hv->vf_lock);
return ret;
}
@@ -536,16 +564,33 @@ int hn_vf_stop(struct rte_eth_dev *dev)
struct hn_data *hv = dev->data->dev_private;
struct rte_eth_dev *vf_dev;
int ret = 0;
+ int err;
- rte_rwlock_read_lock(&hv->vf_lock);
+ rte_rwlock_write_lock(&hv->vf_lock);
vf_dev = hn_get_vf_dev(hv);
if (vf_dev) {
- ret = rte_eth_dev_stop(vf_dev->data->port_id);
- if (ret != 0)
+ /* Switch data path back to synthetic before stopping VF,
+ * so the host stops routing traffic to the VF device.
+ */
+ if (hv->vf_ctx.vf_vsc_switched) {
+ ret = hn_nvs_set_datapath(hv, NVS_DATAPATH_SYNTHETIC);
+ if (ret) {
+ PMD_DRV_LOG(ERR,
+ "Failed to switch to synthetic: %d",
+ ret);
+ } else {
+ hv->vf_ctx.vf_vsc_switched = false;
+ }
+ }
+
+ err = rte_eth_dev_stop(vf_dev->data->port_id);
+ if (err != 0)
PMD_DRV_LOG(ERR, "Failed to stop device on port %u",
vf_dev->data->port_id);
+ if (ret == 0)
+ ret = err;
}
- rte_rwlock_read_unlock(&hv->vf_lock);
+ rte_rwlock_write_unlock(&hv->vf_lock);
return ret;
}
--
2.47.3
---
Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- - 2026-03-26 12:56:34.284804541 +0000
+++ 0021-net-netvsc-switch-data-path-to-synthetic-on-device-s.patch 2026-03-26 12:56:33.453544124 +0000
@@ -1 +1 @@
-From da1fcd9b36d8d6e0dd87518ad675ccc61addf43f Mon Sep 17 00:00:00 2001
+From 4a6b6e4150a3336cf40e9712bbf42a3278cab7e6 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit da1fcd9b36d8d6e0dd87518ad675ccc61addf43f ]
+
@@ -26 +27,0 @@
-Cc: stable at dpdk.org
@@ -34 +35 @@
-index 99e8086afa..1fcc65a712 100644
+index e9e52fbcfc..bcc61bf98c 100644
@@ -37 +38 @@
-@@ -314,9 +314,17 @@ int hn_vf_add_unlocked(struct rte_eth_dev *dev, struct hn_data *hv)
+@@ -318,9 +318,17 @@ int hn_vf_add_unlocked(struct rte_eth_dev *dev, struct hn_data *hv)
@@ -58 +59 @@
-@@ -521,11 +529,31 @@ int hn_vf_start(struct rte_eth_dev *dev)
+@@ -523,11 +531,31 @@ int hn_vf_start(struct rte_eth_dev *dev)
@@ -93 +94 @@
-@@ -534,16 +562,33 @@ int hn_vf_stop(struct rte_eth_dev *dev)
+@@ -536,16 +564,33 @@ int hn_vf_stop(struct rte_eth_dev *dev)
More information about the stable
mailing list