* [PATCH 0/2] net/netvsc: fix stale link status and speed
@ 2026-10-14 2:07 Shrey Khandelwal
2026-10-14 2:07 ` [PATCH 1/2] net/netvsc: fix link speed not updated Shrey Khandelwal
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Shrey Khandelwal @ 2026-10-14 2:07 UTC (permalink / raw)
To: weh; +Cc: longli, stephen, dev
With LSC enabled, the link status and speed seen by the application
are not updated after the host reports a link change.
Patch 1 makes sure the cached link always has the current speed.
Patch 2 updates the cached link from the host indication.
Tested on Azure with testpmd, by injecting media disconnect, media
connect and link speed change indications. Without the patches, the
link read in the LSC callback stays up at the old speed. With them,
it goes down, up, then shows the new speed.
Shrey Khandelwal (2):
net/netvsc: fix link speed not updated
net/netvsc: fix link status not updated on host indication
.mailmap | 1 +
drivers/net/netvsc/hn_ethdev.c | 8 ++-
drivers/net/netvsc/hn_rndis.c | 90 ++++++++++++++++++++++++++++++++--
drivers/net/netvsc/hn_rndis.h | 3 +-
drivers/net/netvsc/hn_rxtx.c | 2 +-
drivers/net/netvsc/hn_var.h | 4 ++
6 files changed, 97 insertions(+), 11 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] net/netvsc: fix link speed not updated
2026-10-14 2:07 [PATCH 0/2] net/netvsc: fix stale link status and speed Shrey Khandelwal
@ 2026-10-14 2:07 ` Shrey Khandelwal
2026-10-14 2:07 ` [PATCH 2/2] net/netvsc: fix link status not updated on host indication Shrey Khandelwal
2026-10-14 17:33 ` [PATCH 0/2] net/netvsc: fix stale link status and speed Stephen Hemminger
2 siblings, 0 replies; 4+ messages in thread
From: Shrey Khandelwal @ 2026-10-14 2:07 UTC (permalink / raw)
To: weh; +Cc: longli, stephen, dev, stable
hn_dev_link_update() returns without updating the cached link when
the link status has not changed. A speed change alone is never
reported, and if the link is down at port start, the cached speed
and duplex stay zero.
Always update the cached link, and only log when the status changes.
Fixes: 4e9c73e96e83 ("net/netvsc: add Hyper-V network device")
Cc: stable@dpdk.org
Signed-off-by: Shrey Khandelwal <s.khandelwal@f5.com>
---
.mailmap | 1 +
drivers/net/netvsc/hn_ethdev.c | 8 +++-----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/.mailmap b/.mailmap
index 2e348c3bce..131b9f86cb 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1558,6 +1558,7 @@ Shlomi Gridish <sgridish@marvell.com>
Shougang Wang <shougangx.wang@intel.com>
Shraddha Joshi <jshraddha@vmware.com>
Shreesh Adiga <16567adigashreesh@gmail.com>
+Shrey Khandelwal <s.khandelwal@f5.com>
Shreyansh Jain <shreyansh.jain@nxp.com>
Shrikrishna Khare <skhare@vmware.com>
Shu Shen <shu.shen@radisys.com>
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index e4fdf89873..5dc91f9503 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -298,11 +298,9 @@ hn_dev_link_update(struct rte_eth_dev *dev,
else
link.link_status = RTE_ETH_LINK_DOWN;
- if (old.link_status == link.link_status)
- return 0;
-
- PMD_INIT_LOG(DEBUG, "Port %d is %s", dev->data->port_id,
- (link.link_status == RTE_ETH_LINK_UP) ? "up" : "down");
+ if (old.link_status != link.link_status)
+ PMD_INIT_LOG(DEBUG, "Port %d is %s", dev->data->port_id,
+ (link.link_status == RTE_ETH_LINK_UP) ? "up" : "down");
return rte_eth_linkstatus_set(dev, &link);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] net/netvsc: fix link status not updated on host indication
2026-10-14 2:07 [PATCH 0/2] net/netvsc: fix stale link status and speed Shrey Khandelwal
2026-10-14 2:07 ` [PATCH 1/2] net/netvsc: fix link speed not updated Shrey Khandelwal
@ 2026-10-14 2:07 ` Shrey Khandelwal
2026-10-14 17:33 ` [PATCH 0/2] net/netvsc: fix stale link status and speed Stephen Hemminger
2 siblings, 0 replies; 4+ messages in thread
From: Shrey Khandelwal @ 2026-10-14 2:07 UTC (permalink / raw)
To: weh; +Cc: longli, stephen, dev, stable
With LSC enabled and the port started, rte_eth_link_get() returns
the cached link. When the host reports a link change, the alarm only
calls the LSC callback and nothing updates the cached link, so the
application keeps seeing the old link status and speed.
The indication already has the new state: media connect or disconnect
for the status, and the new speed in the status buffer. Save it when
the indication is received, and apply it to the cached link in the
alarm before calling the LSC callback. The callback is only called if
the link changed. If several indications arrive before the alarm
runs, the latest state is used. Indications received while the port
is stopped are dropped, as the link is queried when the port starts.
Querying the host from the alarm instead could block the interrupt
thread for up to 60 seconds, and fails with -EBUSY while another
RNDIS request is pending.
Check the message length before reading it, and the status buffer
offset and length before reading the speed.
Fixes: 501a7e573564 ("net/netvsc: process link change messages in alarm")
Cc: stable@dpdk.org
Signed-off-by: Shrey Khandelwal <s.khandelwal@f5.com>
---
drivers/net/netvsc/hn_rndis.c | 90 +++++++++++++++++++++++++++++++++--
drivers/net/netvsc/hn_rndis.h | 3 +-
drivers/net/netvsc/hn_rxtx.c | 2 +-
drivers/net/netvsc/hn_var.h | 4 ++
4 files changed, 93 insertions(+), 6 deletions(-)
diff --git a/drivers/net/netvsc/hn_rndis.c b/drivers/net/netvsc/hn_rndis.c
index 4e13d7c38f..5a965564b2 100644
--- a/drivers/net/netvsc/hn_rndis.c
+++ b/drivers/net/netvsc/hn_rndis.c
@@ -294,12 +294,76 @@ static int hn_nvs_send_rndis_ctrl(struct hn_data *hv,
*/
static void hn_rndis_link_alarm(void *arg)
{
- rte_eth_dev_callback_process(arg, RTE_ETH_EVENT_INTR_LSC, NULL);
+ struct rte_eth_dev *dev = arg;
+ struct hn_data *hv = dev->data->dev_private;
+ struct rte_eth_link link, old;
+ uint32_t status, speed;
+
+ status = rte_atomic_exchange_explicit(&hv->link_ind_status, 0,
+ rte_memory_order_relaxed);
+ speed = rte_atomic_exchange_explicit(&hv->link_ind_speed, 0,
+ rte_memory_order_relaxed);
+
+ /* If stopped, the link is queried when the port starts. */
+ if ((status == 0 && speed == 0) || !dev->data->dev_started)
+ return;
+
+ rte_eth_linkstatus_get(dev, &old);
+ link = old;
+ if (status == RNDIS_STATUS_MEDIA_CONNECT)
+ link.link_status = RTE_ETH_LINK_UP;
+ else if (status == RNDIS_STATUS_MEDIA_DISCONNECT)
+ link.link_status = RTE_ETH_LINK_DOWN;
+ if (speed != 0)
+ link.link_speed = speed / 10000;
+ if (link.link_status == old.link_status &&
+ link.link_speed == old.link_speed)
+ return;
+
+ rte_eth_linkstatus_set(dev, &link);
+ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+}
+
+static void
+hn_rndis_link_alarm_set(struct rte_eth_dev *dev)
+{
+ if (rte_eal_alarm_set(10, hn_rndis_link_alarm, dev) != 0)
+ PMD_DRV_LOG(ERR, "port %u: cannot schedule link update",
+ dev->data->port_id);
+}
+
+/*
+ * Get the link speed, in 100 bps units, from the status buffer.
+ * Use the received length, as older hosts do not count the status
+ * buffer in the message length.
+ */
+static int
+hn_rndis_link_speed_get(const struct rndis_status_msg *indicate,
+ uint32_t len, uint32_t *speed)
+{
+ uint32_t ofs;
+
+ ofs = RNDIS_STBUFOFFSET_ABS(indicate->stbufoffset);
+ if (indicate->stbuflen < sizeof(*speed) ||
+ ofs < sizeof(*indicate) || ofs > len ||
+ len - ofs < indicate->stbuflen)
+ return -EINVAL;
+
+ memcpy(speed, (const uint8_t *)indicate + ofs, sizeof(*speed));
+ return 0;
}
-void hn_rndis_link_status(struct rte_eth_dev *dev, const void *msg)
+void hn_rndis_link_status(struct rte_eth_dev *dev, const void *msg,
+ uint32_t len)
{
const struct rndis_status_msg *indicate = msg;
+ struct hn_data *hv = dev->data->dev_private;
+ uint32_t speed;
+
+ if (len < sizeof(*indicate)) {
+ PMD_DRV_LOG(ERR, "truncated RNDIS status message: len %u", len);
+ return;
+ }
hn_rndis_dump(msg);
@@ -312,10 +376,28 @@ void hn_rndis_link_status(struct rte_eth_dev *dev, const void *msg)
break;
case RNDIS_STATUS_LINK_SPEED_CHANGE:
+ if (!dev->data->dev_conf.intr_conf.lsc)
+ break;
+ if (hn_rndis_link_speed_get(indicate, len, &speed) != 0) {
+ PMD_DRV_LOG(ERR,
+ "invalid link speed indication: len %u buf %u:%u",
+ len, indicate->stbufoffset,
+ indicate->stbuflen);
+ break;
+ }
+ rte_atomic_store_explicit(&hv->link_ind_speed, speed,
+ rte_memory_order_relaxed);
+ hn_rndis_link_alarm_set(dev);
+ break;
+
case RNDIS_STATUS_MEDIA_CONNECT:
case RNDIS_STATUS_MEDIA_DISCONNECT:
- if (dev->data->dev_conf.intr_conf.lsc)
- rte_eal_alarm_set(10, hn_rndis_link_alarm, dev);
+ if (!dev->data->dev_conf.intr_conf.lsc)
+ break;
+ rte_atomic_store_explicit(&hv->link_ind_status,
+ indicate->status,
+ rte_memory_order_relaxed);
+ hn_rndis_link_alarm_set(dev);
break;
default:
PMD_DRV_LOG(NOTICE, "unknown RNDIS indication: %#x",
diff --git a/drivers/net/netvsc/hn_rndis.h b/drivers/net/netvsc/hn_rndis.h
index 7f40f6221d..524b8f221f 100644
--- a/drivers/net/netvsc/hn_rndis.h
+++ b/drivers/net/netvsc/hn_rndis.h
@@ -6,7 +6,8 @@ struct hn_data;
void hn_rndis_receive_response(struct hn_data *hv,
const void *data, uint32_t len);
-void hn_rndis_link_status(struct rte_eth_dev *dev, const void *msg);
+void hn_rndis_link_status(struct rte_eth_dev *dev, const void *msg,
+ uint32_t len);
int hn_rndis_attach(struct hn_data *hv);
void hn_rndis_detach(struct hn_data *hv);
int hn_rndis_get_eaddr(struct hn_data *hv, uint8_t *eaddr);
diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c
index 6f536610f2..9a04861005 100644
--- a/drivers/net/netvsc/hn_rxtx.c
+++ b/drivers/net/netvsc/hn_rxtx.c
@@ -774,7 +774,7 @@ hn_rndis_receive(struct rte_eth_dev *dev, struct hn_rx_queue *rxq,
break;
case RNDIS_INDICATE_STATUS_MSG:
- hn_rndis_link_status(dev, buf);
+ hn_rndis_link_status(dev, buf, len);
break;
case RNDIS_INITIALIZE_CMPLT:
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index d7124a7df9..7d9a950816 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -144,6 +144,10 @@ struct hn_data {
uint32_t link_status;
uint32_t link_speed;
+ /* Pending host link indication, applied by the link alarm */
+ RTE_ATOMIC(uint32_t) link_ind_status; /* RNDIS_STATUS_MEDIA_* or 0 */
+ RTE_ATOMIC(uint32_t) link_ind_speed; /* in 100 bps, or 0 */
+
struct rte_mem_resource rxbuf_res; /* UIO resource for Rx */
uint32_t rxbuf_section_cnt; /* # of Rx sections */
uint32_t rx_copybreak;
--
2.55.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] net/netvsc: fix stale link status and speed
2026-10-14 2:07 [PATCH 0/2] net/netvsc: fix stale link status and speed Shrey Khandelwal
2026-10-14 2:07 ` [PATCH 1/2] net/netvsc: fix link speed not updated Shrey Khandelwal
2026-10-14 2:07 ` [PATCH 2/2] net/netvsc: fix link status not updated on host indication Shrey Khandelwal
@ 2026-10-14 17:33 ` Stephen Hemminger
2 siblings, 0 replies; 4+ messages in thread
From: Stephen Hemminger @ 2026-10-14 17:33 UTC (permalink / raw)
To: Shrey Khandelwal; +Cc: weh, longli, dev
On Tue, 13 Oct 2026 19:07:42 -0700
Shrey Khandelwal <s.khandelwal@f5.com> wrote:
> With LSC enabled, the link status and speed seen by the application
> are not updated after the host reports a link change.
>
> Patch 1 makes sure the cached link always has the current speed.
> Patch 2 updates the cached link from the host indication.
>
> Tested on Azure with testpmd, by injecting media disconnect, media
> connect and link speed change indications. Without the patches, the
> link read in the LSC callback stays up at the old speed. With them,
> it goes down, up, then shows the new speed.
>
> Shrey Khandelwal (2):
> net/netvsc: fix link speed not updated
> net/netvsc: fix link status not updated on host indication
>
> .mailmap | 1 +
> drivers/net/netvsc/hn_ethdev.c | 8 ++-
> drivers/net/netvsc/hn_rndis.c | 90 ++++++++++++++++++++++++++++++++--
> drivers/net/netvsc/hn_rndis.h | 3 +-
> drivers/net/netvsc/hn_rxtx.c | 2 +-
> drivers/net/netvsc/hn_var.h | 4 ++
> 6 files changed, 97 insertions(+), 11 deletions(-)
>
Looks correct and review was clean. applied to next-net
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-14 17:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-14 2:07 [PATCH 0/2] net/netvsc: fix stale link status and speed Shrey Khandelwal
2026-10-14 2:07 ` [PATCH 1/2] net/netvsc: fix link speed not updated Shrey Khandelwal
2026-10-14 2:07 ` [PATCH 2/2] net/netvsc: fix link status not updated on host indication Shrey Khandelwal
2026-10-14 17:33 ` [PATCH 0/2] net/netvsc: fix stale link status and speed Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox