git: 80c3eb7bc64b - main - Hyper-V: hn: add switch to turn on and off RSC

From: Wei Hu <whu_at_FreeBSD.org>
Date: Tue, 15 Mar 2022 08:16:27 UTC
The branch main has been updated by whu:

URL: https://cgit.FreeBSD.org/src/commit/?id=80c3eb7bc64b745b2a0bda953e29a26e32dff9d7

commit 80c3eb7bc64b745b2a0bda953e29a26e32dff9d7
Author:     Wei Hu <whu@FreeBSD.org>
AuthorDate: 2022-03-15 07:56:38 +0000
Commit:     Wei Hu <whu@FreeBSD.org>
CommitDate: 2022-03-15 08:12:22 +0000

    Hyper-V: hn: add switch to turn on and off RSC
    
    Currently RSC offloading is enabled by default.
    With this new change rsc will be disabled by default.
    By using sysctl we can enable and disable it.
    
    Reviewed by:    whu
    Signed-off-by:  Souradeep Chakrabarti <schakrabarti@microsoft.com>
    Fixes:          a491581f3f8df Enable vSwitch RSC support in hn netvsc driver
    MFC after:      1 week
    Sponsored by:   Microsoft
    Differential Revision:  https://reviews.freebsd.org/D34507
---
 sys/dev/hyperv/netvsc/hn_rndis.c |  9 ++++++++-
 sys/dev/hyperv/netvsc/hn_rndis.h |  1 +
 sys/dev/hyperv/netvsc/if_hn.c    | 30 ++++++++++++++++++++++++++++++
 sys/dev/hyperv/netvsc/if_hnvar.h |  5 +++++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/sys/dev/hyperv/netvsc/hn_rndis.c b/sys/dev/hyperv/netvsc/hn_rndis.c
index 108950aa3f9b..58167312c9f3 100644
--- a/sys/dev/hyperv/netvsc/hn_rndis.c
+++ b/sys/dev/hyperv/netvsc/hn_rndis.c
@@ -579,6 +579,12 @@ done:
 	return (error);
 }
 
+int
+hn_rndis_reconf_offload(struct hn_softc *sc, int mtu)
+{
+	return(hn_rndis_conf_offload(sc, mtu));
+}
+
 static int
 hn_rndis_conf_offload(struct hn_softc *sc, int mtu)
 {
@@ -725,7 +731,8 @@ hn_rndis_conf_offload(struct hn_softc *sc, int mtu)
 
 	/* RSC offload */
 	if (hwcaps.ndis_hdr.ndis_rev >= NDIS_OFFLOAD_PARAMS_REV_3) {
-		if (hwcaps.ndis_rsc.ndis_ip4 && hwcaps.ndis_rsc.ndis_ip6) {
+		if (hwcaps.ndis_rsc.ndis_ip4 && hwcaps.ndis_rsc.ndis_ip6 &&
+		    sc->hn_rsc_ctrl) {
 			params.ndis_rsc_ip4 = NDIS_OFFLOAD_RSC_ON;
 			params.ndis_rsc_ip6 = NDIS_OFFLOAD_RSC_ON;
 		} else {
diff --git a/sys/dev/hyperv/netvsc/hn_rndis.h b/sys/dev/hyperv/netvsc/hn_rndis.h
index 4610d5a10526..6e4db9b0bb30 100644
--- a/sys/dev/hyperv/netvsc/hn_rndis.h
+++ b/sys/dev/hyperv/netvsc/hn_rndis.h
@@ -46,5 +46,6 @@ int		hn_rndis_get_mtu(struct hn_softc *sc, uint32_t *mtu);
 int		hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter);
 void		hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data,
 		    int dlen);
+int		hn_rndis_reconf_offload(struct hn_softc *sc, int mtu);
 
 #endif  /* !_HN_RNDIS_H_ */
diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c
index 3d13bd696c94..95f62902fe6b 100644
--- a/sys/dev/hyperv/netvsc/if_hn.c
+++ b/sys/dev/hyperv/netvsc/if_hn.c
@@ -454,6 +454,8 @@ static void			hn_start_txeof(struct hn_tx_ring *);
 static void			hn_start_txeof_taskfunc(void *, int);
 #endif
 
+static int			hn_rsc_sysctl(SYSCTL_HANDLER_ARGS);
+
 SYSCTL_NODE(_hw, OID_AUTO, hn, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
     "Hyper-V network interface");
 
@@ -2370,6 +2372,10 @@ hn_attach(device_t dev)
 		    "Accurate BPF for transparent VF");
 	}
 
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rsc_switch",
+	    CTLTYPE_UINT | CTLFLAG_RW, sc, 0, hn_rsc_sysctl, "A",
+	    "switch to rsc");
+
 	/*
 	 * Setup the ifmedia, which has been initialized earlier.
 	 */
@@ -4567,6 +4573,30 @@ hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS)
 	return sysctl_handle_string(oidp, filter_str, sizeof(filter_str), req);
 }
 
+static int
+hn_rsc_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	struct hn_softc *sc = arg1;
+	uint32_t 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));
+	if (error || req->newptr == NULL)
+		goto back;
+
+	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
 
 static int
diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h
index 27d93db5395e..7b23f0ec7cbf 100644
--- a/sys/dev/hyperv/netvsc/if_hnvar.h
+++ b/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -282,6 +282,11 @@ struct hn_softc {
 	u_int			hn_saved_tsomax;
 	u_int			hn_saved_tsosegcnt;
 	u_int			hn_saved_tsosegsz;
+
+	/*
+	 * RSC switch, default off
+	 */
+	u_int			hn_rsc_ctrl;
 };
 
 #define HN_FLAG_RXBUF_CONNECTED		0x0001