diff options
author | Wei Hu <whu@FreeBSD.org> | 2025-02-04 13:39:14 +0000 |
---|---|---|
committer | Wei Hu <whu@FreeBSD.org> | 2025-02-04 13:39:14 +0000 |
commit | da1deb784d9ad3a4015a3f91fa1a5ce394fd3fdb (patch) | |
tree | 18f03f79714360bc4d99eb74a0425639da7a13bf | |
parent | ff977fd34b4bb85cf27b55106131b4dd6594afab (diff) |
Hyper-V: hn: rewrite hn rsc swtich to avoid sysctl hang
Changing the rsc_switch flag using sysctl to turn rsc on or off
could hang. The orignal code sends request to host to get the
mtu setting. Sometimes the host fails to reply, causing
the thread to sleep forever waiting for the host response.
Use existing cached mtu from hn device instead to avoid calling
host.
Reported by: whu
Tested by: whu
MFC after: 1 week
-rw-r--r-- | sys/dev/hyperv/netvsc/if_hn.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c index 212b6bc0ff57..ab7671025107 100644 --- a/sys/dev/hyperv/netvsc/if_hn.c +++ b/sys/dev/hyperv/netvsc/if_hn.c @@ -2355,7 +2355,7 @@ hn_attach(device_t dev) } SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rsc_switch", - CTLTYPE_UINT | CTLFLAG_RW, sc, 0, hn_rsc_sysctl, "A", + CTLTYPE_UINT | CTLFLAG_RW, sc, 0, hn_rsc_sysctl, "I", "switch to rsc"); /* @@ -4523,24 +4523,22 @@ static int hn_rsc_sysctl(SYSCTL_HANDLER_ARGS) { struct hn_softc *sc = arg1; - uint32_t mtu; + int rsc_ctrl, mtu; int error; - HN_LOCK(sc); - error = hn_rndis_get_mtu(sc, &mtu); - if (error) { - if_printf(sc->hn_ifp, "failed to get mtu\n"); - goto back; - } - error = SYSCTL_OUT(req, &(sc->hn_rsc_ctrl), sizeof(sc->hn_rsc_ctrl)); + + rsc_ctrl = sc->hn_rsc_ctrl; + error = sysctl_handle_int(oidp, &rsc_ctrl, 0, req); if (error || req->newptr == NULL) - goto back; + return (error); + + if (sc->hn_rsc_ctrl != rsc_ctrl) { + HN_LOCK(sc); + sc->hn_rsc_ctrl = rsc_ctrl; + mtu = if_getmtu(sc->hn_ifp); + error = hn_rndis_reconf_offload(sc, mtu); + HN_UNLOCK(sc); + } - error = SYSCTL_IN(req, &(sc->hn_rsc_ctrl), sizeof(sc->hn_rsc_ctrl)); - if (error) - goto back; - error = hn_rndis_reconf_offload(sc, mtu); -back: - HN_UNLOCK(sc); return (error); } #ifndef RSS |