Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Sep 2023 10:40:50 GMT
From:      Wei Hu <whu@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 289ba6b870f7 - main - Hyper-V: hn: use VF's capabilities when it is attached
Message-ID:  <202309041040.384Aeohp011159@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by whu:

URL: https://cgit.FreeBSD.org/src/commit/?id=289ba6b870f79d8dbd9e8022c4fa23469be11a73

commit 289ba6b870f79d8dbd9e8022c4fa23469be11a73
Author:     Wei Hu <whu@FreeBSD.org>
AuthorDate: 2023-09-04 10:15:06 +0000
Commit:     Wei Hu <whu@FreeBSD.org>
CommitDate: 2023-09-04 10:40:11 +0000

    Hyper-V: hn: use VF's capabilities when it is attached
    
    Current code in hn/netvsc tries to merge  (logical AND) VF and
    its own capability bits when a VF is attached. This results in
    losing some key VF features, especially in tx path. For example,
    the VF's txcsum, rxcsum or tso bits could be lost if any of
    these are not in hn/netvsc's own capablility field.
    
    Actually when VF is attached, hn just needs to use VF's caps
    as all the tx packets would be forwarded to the VF interface.
    Fix this problem by doing so.
    
    Reported by:    whu
    Tested by:      whu
    MFC after:      3 days
    Sponsored by:   Microsoft
---
 sys/dev/hyperv/netvsc/if_hn.c    | 63 +++++++---------------------------------
 sys/dev/hyperv/netvsc/if_hnvar.h |  2 ++
 2 files changed, 13 insertions(+), 52 deletions(-)

diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c
index 206a35f7bac8..7d8e1914163e 100644
--- a/sys/dev/hyperv/netvsc/if_hn.c
+++ b/sys/dev/hyperv/netvsc/if_hn.c
@@ -1261,60 +1261,21 @@ hn_ifaddr_event(void *arg, if_t ifp)
 }
 
 static int
-hn_xpnt_vf_iocsetcaps(struct hn_softc *sc, struct ifreq *ifr)
+hn_xpnt_vf_iocsetcaps(struct hn_softc *sc, struct ifreq *ifr __unused)
 {
 	if_t ifp, vf_ifp;
-	uint64_t tmp;
-	int error;
 
 	HN_LOCK_ASSERT(sc);
 	ifp = sc->hn_ifp;
 	vf_ifp = sc->hn_vf_ifp;
 
 	/*
-	 * Fix up requested capabilities w/ supported capabilities,
-	 * since the supported capabilities could have been changed.
-	 */
-	ifr->ifr_reqcap &= if_getcapabilities(ifp);
-	/* Pass SIOCSIFCAP to VF. */
-	error = ifhwioctl(SIOCSIFCAP, vf_ifp, (caddr_t)ifr, curthread);
-
-	/*
-	 * NOTE:
-	 * The error will be propagated to the callers, however, it
-	 * is _not_ useful here.
-	 */
-
-	/*
-	 * Merge VF's enabled capabilities.
+	 * Just sync up with VF's enabled capabilities.
 	 */
-	if_setcapenable(ifp, if_getcapenable(vf_ifp) & if_getcapabilities(ifp));
-
-	tmp = if_gethwassist(vf_ifp) & HN_CSUM_IP_HWASSIST(sc);
-	if (if_getcapenable(ifp) & IFCAP_TXCSUM)
-		if_sethwassistbits(ifp, tmp, 0);
-	else
-		if_sethwassistbits(ifp, 0, tmp);
-
-	tmp = if_gethwassist(vf_ifp) & HN_CSUM_IP6_HWASSIST(sc);
-	if (if_getcapenable(ifp) & IFCAP_TXCSUM_IPV6)
-		if_sethwassistbits(ifp, tmp, 0);
-	else
-		if_sethwassistbits(ifp, 0, tmp);
+	if_setcapenable(ifp, if_getcapenable(vf_ifp));
+	if_sethwassist(ifp, if_gethwassist(vf_ifp));
 
-	tmp = if_gethwassist(vf_ifp) & CSUM_IP_TSO;
-	if (if_getcapenable(ifp) & IFCAP_TSO4)
-		if_sethwassistbits(ifp, tmp, 0);
-	else
-		if_sethwassistbits(ifp, 0, tmp);
-
-	tmp = if_gethwassist(vf_ifp) & CSUM_IP6_TSO;
-	if (if_getcapenable(ifp) & IFCAP_TSO6)
-		if_sethwassistbits(ifp, tmp, 0);
-	else
-		if_sethwassistbits(ifp, 0, tmp);
-
-	return (error);
+	return (0);
 }
 
 static int
@@ -1698,6 +1659,8 @@ hn_xpnt_vf_setready(struct hn_softc *sc)
 	sc->hn_saved_tsomax = if_gethwtsomax(ifp);
 	sc->hn_saved_tsosegcnt = if_gethwtsomaxsegcount(ifp);
 	sc->hn_saved_tsosegsz = if_gethwtsomaxsegsize(ifp);
+	sc->hn_saved_capenable = if_getcapenable(ifp);
+	sc->hn_saved_hwassist = if_gethwassist(ifp);
 
 	/*
 	 * Intersect supported/enabled capabilities.
@@ -2017,18 +1980,14 @@ hn_ifnet_detevent(void *xsc, if_t ifp)
 			 * The VF was ready; restore some settings.
 			 */
 			if_setcapabilities(ifp, sc->hn_saved_caps);
-			/*
-			 * NOTE:
-			 * There is _no_ need to fixup if_capenable and
-			 * if_hwassist, since the if_capabilities before
-			 * restoration was an intersection of the VF's
-			 * if_capabilites and the synthetic device's
-			 * if_capabilites.
-			 */
+
 			if_sethwtsomax(ifp, sc->hn_saved_tsomax);
 			if_sethwtsomaxsegcount(sc->hn_ifp,
 			    sc->hn_saved_tsosegcnt);
 			if_sethwtsomaxsegsize(ifp, sc->hn_saved_tsosegsz);
+
+			if_setcapenable(ifp, sc->hn_saved_capenable);
+			if_sethwassist(ifp, sc->hn_saved_hwassist);
 		}
 
 		if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) {
diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h
index 0d8ed6bdef19..f46adcbf9245 100644
--- a/sys/dev/hyperv/netvsc/if_hnvar.h
+++ b/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -277,6 +277,8 @@ struct hn_softc {
 	u_int			hn_saved_tsomax;
 	u_int			hn_saved_tsosegcnt;
 	u_int			hn_saved_tsosegsz;
+	u_int			hn_saved_capenable;
+	u_int			hn_saved_hwassist;
 
 	/*
 	 * RSC switch, default off



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202309041040.384Aeohp011159>