mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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. MFC after: 2 weeks Sponsored by: BBOX.io
This commit is contained in:
1 parent
a64205b135
commit
6b3b1d6d4f
1 file changed
+8
-1
@@ -2132,10 +2132,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
|
||||
@@ -7527,6 +7533,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;
|
||||
|
||||
Reference in new issue
Block a user