git: 544102932584 - stable/15 - hn: Serialize VF link events with datapath handoff
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 29 Oct 2026 05:01:42 UTC
The branch stable/15 has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=544102932584a66a52a4dacc166ba8a1c32b936c
commit 544102932584a66a52a4dacc166ba8a1c32b936c
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-09-15 00:22:13 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-10-29 05:01:32 +0000
hn: Serialize VF link events with datapath handoff
Hold hn_vf_lock across the VF identity/state check and link publication.
Otherwise an event can observe an enabled VF, pause during fallback, then
overwrite the freshly reported synthetic carrier with stale VF state.
Ignore events while switching or after the association generation changes.
The link notification only queues further work, so the callback does not
need the sleepable hn lock.
Document that association serial numbers are currently diagnostic:
hn_ismyvf() matches the VF by MAC, while notifications gate availability.
Sponsored by: BBOX.io
(cherry picked from commit 6b3b1d6d4f43d1521e5e10b759e3542deaf23667)
---
sys/dev/hyperv/netvsc/if_hn.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c
index 27a8f517d3f8..fd49a8cb100d 100644
--- a/sys/dev/hyperv/netvsc/if_hn.c
+++ b/sys/dev/hyperv/netvsc/if_hn.c
@@ -2145,10 +2145,16 @@ static void
hn_ifnet_lnkevent(void *xsc, if_t ifp, int link_state)
{
struct hn_softc *sc = xsc;
+ struct rm_priotracker pt;
+ /* Publish before a concurrent handoff can restore synthetic carrier. */
+ rm_rlock(&sc->hn_vf_lock, &pt);
if (sc->hn_vf_ifp == ifp &&
- (sc->hn_xvf_flags & HN_XVFFLAG_ENABLED))
+ (sc->hn_xvf_flags & (HN_XVFFLAG_ENABLED | HN_XVFFLAG_SWITCHING)) ==
+ HN_XVFFLAG_ENABLED && sc->hn_vf_active_assoc ==
+ atomic_load_acq_int(&sc->hn_vf_assoc))
if_link_state_change(sc->hn_ifp, link_state);
+ rm_runlock(&sc->hn_vf_lock, &pt);
}
static int
@@ -7544,6 +7550,7 @@ hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
if_printf(sc->hn_ifp, "invalid VF association notification\n");
return;
}
+ /* The serial is diagnostic; hn_ismyvf() matches the VF by MAC. */
/* Preserve withdrawals even when the worker coalesces notices. */
state = (atomic_load_int(&sc->hn_vf_assoc) + HN_VF_ASSOC_GENINC) &
~HN_VF_ASSOC_ALLOCATED;