Skip to content

Commit

Permalink
Hyper-V: hn: Enable vSwitch RSC support in hn netvsc driver
Browse files Browse the repository at this point in the history
Receive Segment Coalescing (RSC) in the vSwitch is a feature available in
Windows Server 2019 hosts and later. It reduces the per packet processing
overhead by coalescing multiple TCP segments when possible. This happens
mostly when TCP traffics are among different guests on same host.
This patch adds netvsc driver support for this feature.

The patch also updates NVS version to 6.1 as needed for RSC
enablement.

MFC after:	2 weeks
Sponsored by:	Microsoft
Differential Revision:	https://reviews.freebsd.org/D29075

(cherry picked from commit a491581)
  • Loading branch information
Wei Hu authored and Wei Hu committed Mar 29, 2021
1 parent a86be0d commit cdc5916
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 90 deletions.
5 changes: 5 additions & 0 deletions sys/dev/hyperv/netvsc/hn_nvs.c
Expand Up @@ -80,6 +80,8 @@ struct hn_nvs_sendctx hn_nvs_sendctx_none =
HN_NVS_SENDCTX_INITIALIZER(hn_nvs_sent_none, NULL);

static const uint32_t hn_nvs_version[] = {
HN_NVS_VERSION_61,
HN_NVS_VERSION_6,
HN_NVS_VERSION_5,
HN_NVS_VERSION_4,
HN_NVS_VERSION_2,
Expand Down Expand Up @@ -508,6 +510,9 @@ hn_nvs_conf_ndis(struct hn_softc *sc, int mtu)
conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN;
if (sc->hn_nvs_ver >= HN_NVS_VERSION_5)
conf.nvs_caps |= HN_NVS_NDIS_CONF_SRIOV;
if (sc->hn_nvs_ver >= HN_NVS_VERSION_61)
conf.nvs_caps |= HN_NVS_NDIS_CONF_RSC;


/* NOTE: No response. */
error = hn_nvs_req_send(sc, &conf, sizeof(conf));
Expand Down
25 changes: 25 additions & 0 deletions sys/dev/hyperv/netvsc/hn_rndis.c
Expand Up @@ -723,6 +723,17 @@ hn_rndis_conf_offload(struct hn_softc *sc, int mtu)
params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_RX;
}

/* RSC offload */
if (hwcaps.ndis_hdr.ndis_rev >= NDIS_OFFLOAD_PARAMS_REV_3) {
if (hwcaps.ndis_rsc.ndis_ip4 && hwcaps.ndis_rsc.ndis_ip6) {
params.ndis_rsc_ip4 = NDIS_OFFLOAD_RSC_ON;
params.ndis_rsc_ip6 = NDIS_OFFLOAD_RSC_ON;
} else {
params.ndis_rsc_ip4 = NDIS_OFFLOAD_RSC_OFF;
params.ndis_rsc_ip6 = NDIS_OFFLOAD_RSC_OFF;
}
}

if (bootverbose) {
if_printf(sc->hn_ifp, "offload csum: "
"ip4 %u, tcp4 %u, udp4 %u, tcp6 %u, udp6 %u\n",
Expand All @@ -734,6 +745,10 @@ hn_rndis_conf_offload(struct hn_softc *sc, int mtu)
if_printf(sc->hn_ifp, "offload lsov2: ip4 %u, ip6 %u\n",
params.ndis_lsov2_ip4,
params.ndis_lsov2_ip6);
if (hwcaps.ndis_hdr.ndis_rev >= NDIS_OFFLOAD_PARAMS_REV_3)
if_printf(sc->hn_ifp, "offload rsc: ip4 %u, ip6 %u\n",
params.ndis_rsc_ip4,
params.ndis_rsc_ip6);
}

error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, &params, paramsz);
Expand Down Expand Up @@ -969,6 +984,11 @@ hn_rndis_query_hwcaps(struct hn_softc *sc, struct ndis_offload *caps)
if_printf(sc->hn_ifp, "invalid NDIS objsize %u\n",
caps->ndis_hdr.ndis_size);
return (EINVAL);
} else if (caps->ndis_hdr.ndis_rev >= NDIS_OFFLOAD_REV_3 &&
caps->ndis_hdr.ndis_size < NDIS_OFFLOAD_SIZE) {
if_printf(sc->hn_ifp, "invalid NDIS rev3 objsize %u\n",
caps->ndis_hdr.ndis_size);
return (EINVAL);
}

if (bootverbose) {
Expand Down Expand Up @@ -1001,6 +1021,11 @@ hn_rndis_query_hwcaps(struct hn_softc *sc, struct ndis_offload *caps)
caps->ndis_lsov2.ndis_ip6_minsg,
caps->ndis_lsov2.ndis_ip6_encap,
caps->ndis_lsov2.ndis_ip6_opts);
if (caps->ndis_hdr.ndis_rev >= NDIS_OFFLOAD_REV_3)
if_printf(sc->hn_ifp, "hwcaps rsc: "
"ip4 %u ip6 %u\n",
caps->ndis_rsc.ndis_ip4,
caps->ndis_rsc.ndis_ip6);
}
return (0);
}
Expand Down

0 comments on commit cdc5916

Please sign in to comment.