diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2020-04-01 15:30:20 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2020-04-08 04:07:18 -0700 |
commit | 62366fbbe8edca853fee6c14327d822239ba914f (patch) | |
tree | c8a05f17464a8302fc2870a8a2c47b1625b9b9f8 | |
parent | d240edaf609c558d5a1f981b09a577823b54fae2 (diff) | |
download | illumos-joyent-62366fbbe8edca853fee6c14327d822239ba914f.tar.gz |
12466 Enable IPv6 TSO Support for vioif
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Paul Winder <paul@winders.demon.co.uk>
Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r-- | usr/src/uts/common/inet/ip.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_if.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/ip_output.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/io/dld/dld_proto.c | 29 | ||||
-rw-r--r-- | usr/src/uts/common/io/vioif/vioif.c | 21 | ||||
-rw-r--r-- | usr/src/uts/common/io/vioif/vioif.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/sys/dld.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/sys/mac_provider.h | 8 |
9 files changed, 63 insertions, 22 deletions
diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h index f67ade9060..93ae80f303 100644 --- a/usr/src/uts/common/inet/ip.h +++ b/usr/src/uts/common/inet/ip.h @@ -1595,7 +1595,8 @@ struct ill_zerocopy_capab_s { struct ill_lso_capab_s { uint_t ill_lso_flags; /* capabilities */ - uint_t ill_lso_max; /* maximum size of payload */ + uint_t ill_lso_max_tcpv4; /* maximum size of payload */ + uint_t ill_lso_max_tcpv6; /* maximum size of payload */ }; /* diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c index 4704909723..f4642c720d 100644 --- a/usr/src/uts/common/inet/ip/ip_if.c +++ b/usr/src/uts/common/inet/ip/ip_if.c @@ -2080,7 +2080,7 @@ ill_capability_lso_enable(ill_t *ill) dld_capab_lso_t lso; int rc; - ASSERT(!ill->ill_isv6 && IAM_WRITER_ILL(ill)); + ASSERT(IAM_WRITER_ILL(ill)); if (ill->ill_lso_capab == NULL) { ill->ill_lso_capab = kmem_zalloc(sizeof (ill_lso_capab_t), @@ -2097,7 +2097,8 @@ ill_capability_lso_enable(ill_t *ill) if ((rc = idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_LSO, &lso, DLD_ENABLE)) == 0) { ill->ill_lso_capab->ill_lso_flags = lso.lso_flags; - ill->ill_lso_capab->ill_lso_max = lso.lso_max; + ill->ill_lso_capab->ill_lso_max_tcpv4 = lso.lso_max_tcpv4; + ill->ill_lso_capab->ill_lso_max_tcpv6 = lso.lso_max_tcpv6; ill->ill_capabilities |= ILL_CAPAB_LSO; ip1dbg(("ill_capability_lso_enable: interface %s " "has enabled LSO\n ", ill->ill_name)); @@ -2115,15 +2116,12 @@ ill_capability_dld_enable(ill_t *ill) ASSERT(IAM_WRITER_ILL(ill)); - if (ill->ill_isv6) - return; - ill_mac_perim_enter(ill, &mph); if (!ill->ill_isv6) { ill_capability_direct_enable(ill); ill_capability_poll_enable(ill); - ill_capability_lso_enable(ill); } + ill_capability_lso_enable(ill); ill->ill_capabilities |= ILL_CAPAB_DLD; ill_mac_perim_exit(ill, mph); } diff --git a/usr/src/uts/common/inet/ip/ip_output.c b/usr/src/uts/common/inet/ip/ip_output.c index d3d04d4ec5..1017240521 100644 --- a/usr/src/uts/common/inet/ip/ip_output.c +++ b/usr/src/uts/common/inet/ip/ip_output.c @@ -672,7 +672,8 @@ ip_verify_lso(ill_t *ill, ip_xmit_attr_t *ixa) /* * Capability has changed, refresh the copy in ixa. */ - if (lsoc->ill_lso_max != new_lsoc->ill_lso_max) { + if (lsoc->ill_lso_max_tcpv4 != new_lsoc->ill_lso_max_tcpv4 || + lsoc->ill_lso_max_tcpv6 != new_lsoc->ill_lso_max_tcpv6) { *lsoc = *new_lsoc; return (B_FALSE); diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c index cf575fb944..eef7ded43a 100644 --- a/usr/src/uts/common/inet/tcp/tcp.c +++ b/usr/src/uts/common/inet/tcp/tcp.c @@ -3315,9 +3315,11 @@ tcp_update_lso(tcp_t *tcp, ip_xmit_attr_t *ixa) */ if (ixa->ixa_flags & IXAF_LSO_CAPAB) { ill_lso_capab_t *lsoc = &ixa->ixa_lso_capab; + uint_t lso_max = (ixa->ixa_flags & IXAF_IS_IPV4) ? + lsoc->ill_lso_max_tcpv4 : lsoc->ill_lso_max_tcpv6; - ASSERT(lsoc->ill_lso_max > 0); - tcp->tcp_lso_max = MIN(TCP_MAX_LSO_LENGTH, lsoc->ill_lso_max); + ASSERT3U(lso_max, >, 0); + tcp->tcp_lso_max = MIN(TCP_MAX_LSO_LENGTH, lso_max); DTRACE_PROBE3(tcp_update_lso, boolean_t, tcp->tcp_lso, boolean_t, B_TRUE, uint32_t, tcp->tcp_lso_max); diff --git a/usr/src/uts/common/io/dld/dld_proto.c b/usr/src/uts/common/io/dld/dld_proto.c index b7eeb35b92..1e99114b1c 100644 --- a/usr/src/uts/common/io/dld/dld_proto.c +++ b/usr/src/uts/common/io/dld/dld_proto.c @@ -1479,13 +1479,23 @@ dld_capab_lso(dld_str_t *dsp, void *data, uint_t flags) * accordingly. */ if (mac_capab_get(dsp->ds_mh, MAC_CAPAB_LSO, &mac_lso)) { - lso->lso_max = mac_lso.lso_basic_tcp_ipv4.lso_max; + lso->lso_max_tcpv4 = mac_lso.lso_basic_tcp_ipv4.lso_max; + lso->lso_max_tcpv6 = mac_lso.lso_basic_tcp_ipv6.lso_max; lso->lso_flags = 0; /* translate the flag for mac clients */ if ((mac_lso.lso_flags & LSO_TX_BASIC_TCP_IPV4) != 0) lso->lso_flags |= DLD_LSO_BASIC_TCP_IPV4; - dsp->ds_lso = B_TRUE; - dsp->ds_lso_max = lso->lso_max; + if ((mac_lso.lso_flags & LSO_TX_BASIC_TCP_IPV6) != 0) + lso->lso_flags |= DLD_LSO_BASIC_TCP_IPV6; + dsp->ds_lso = lso->lso_flags != 0; + /* + * DLS uses this to try and make sure that a raw ioctl + * doesn't send too much data, but doesn't currently + * check the actual SAP that is sending this (or that + * it's TCP). So for now, just use the max value here. + */ + dsp->ds_lso_max = MAX(lso->lso_max_tcpv4, + lso->lso_max_tcpv6); } else { dsp->ds_lso = B_FALSE; dsp->ds_lso_max = 0; @@ -1515,17 +1525,25 @@ dld_capab(dld_str_t *dsp, uint_t type, void *data, uint_t flags) * completes. So we limit the check to DLD_ENABLE case. */ if ((flags == DLD_ENABLE && type != DLD_CAPAB_PERIM) && - (dsp->ds_sap != ETHERTYPE_IP || + (!(dsp->ds_sap == ETHERTYPE_IP || dsp->ds_sap == ETHERTYPE_IPV6) || !check_mod_above(dsp->ds_rq, "ip"))) { return (ENOTSUP); } switch (type) { case DLD_CAPAB_DIRECT: + if (dsp->ds_sap == ETHERTYPE_IPV6) { + err = ENOTSUP; + break; + } err = dld_capab_direct(dsp, data, flags); break; case DLD_CAPAB_POLL: + if (dsp->ds_sap == ETHERTYPE_IPV6) { + err = ENOTSUP; + break; + } err = dld_capab_poll(dsp, data, flags); break; @@ -1600,7 +1618,8 @@ proto_capability_advertise(dld_str_t *dsp, mblk_t *mp) /* * Direct capability negotiation interface between IP and DLD */ - if (dsp->ds_sap == ETHERTYPE_IP && check_mod_above(dsp->ds_rq, "ip")) { + if ((dsp->ds_sap == ETHERTYPE_IP || dsp->ds_sap == ETHERTYPE_IPV6) && + check_mod_above(dsp->ds_rq, "ip")) { dld_capable = B_TRUE; subsize += sizeof (dl_capability_sub_t) + sizeof (dl_capab_dld_t); diff --git a/usr/src/uts/common/io/vioif/vioif.c b/usr/src/uts/common/io/vioif/vioif.c index ea3d812c96..cac90d3073 100644 --- a/usr/src/uts/common/io/vioif/vioif.c +++ b/usr/src/uts/common/io/vioif/vioif.c @@ -1019,7 +1019,7 @@ vioif_send(vioif_t *vif, mblk_t *mp) for (nmp = mp; nmp; nmp = nmp->b_cont) msg_size += MBLKL(nmp); - if (vif->vif_tx_tso4) { + if (vif->vif_tx_tso4 || vif->vif_tx_tso6) { mac_lso_get(mp, &lso_mss, &lso_flags); lso_required = (lso_flags & HW_LSO) != 0; } @@ -1105,9 +1105,10 @@ vioif_send(vioif_t *vif, mblk_t *mp) goto fail; } - if (meo.meoi_l3proto == ETHERTYPE_IP) { + if (meo.meoi_l3proto == ETHERTYPE_IP && vif->vif_tx_tso4) { vnh->vnh_gso_type = VIRTIO_NET_HDR_GSO_TCPV4; - } else if (meo.meoi_l3proto == ETHERTYPE_IPV6) { + } else if (meo.meoi_l3proto == ETHERTYPE_IPV6 && + vif->vif_tx_tso6) { vnh->vnh_gso_type = VIRTIO_NET_HDR_GSO_TCPV6; } else { goto fail; @@ -1515,8 +1516,9 @@ vioif_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) } mac_capab_lso_t *lso = cap_data; - lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; + lso->lso_flags = LSO_TX_BASIC_TCP_IPV4 | LSO_TX_BASIC_TCP_IPV6; lso->lso_basic_tcp_ipv4.lso_max = VIOIF_RX_DATA_SIZE; + lso->lso_basic_tcp_ipv6.lso_max = VIOIF_RX_DATA_SIZE; return (B_TRUE); } @@ -1618,6 +1620,7 @@ vioif_check_features(vioif_t *vif) vif->vif_tx_csum = 0; vif->vif_tx_tso4 = 0; + vif->vif_tx_tso6 = 0; if (vioif_has_feature(vif, VIRTIO_NET_F_CSUM)) { /* @@ -1631,6 +1634,7 @@ vioif_check_features(vioif_t *vif) */ boolean_t gso = vioif_has_feature(vif, VIRTIO_NET_F_GSO); boolean_t tso4 = vioif_has_feature(vif, VIRTIO_NET_F_HOST_TSO4); + boolean_t tso6 = vioif_has_feature(vif, VIRTIO_NET_F_HOST_TSO6); boolean_t ecn = vioif_has_feature(vif, VIRTIO_NET_F_HOST_ECN); /* @@ -1640,8 +1644,15 @@ vioif_check_features(vioif_t *vif) * we require the device to support the combination of * segmentation offload and ECN support. */ - if (gso || (tso4 && ecn)) { + if (gso) { vif->vif_tx_tso4 = 1; + vif->vif_tx_tso6 = 1; + } + if (tso4 && ecn) { + vif->vif_tx_tso4 = 1; + } + if (tso6 && ecn) { + vif->vif_tx_tso6 = 1; } } } diff --git a/usr/src/uts/common/io/vioif/vioif.h b/usr/src/uts/common/io/vioif/vioif.h index 19d8965bd4..9f750c9b8a 100644 --- a/usr/src/uts/common/io/vioif/vioif.h +++ b/usr/src/uts/common/io/vioif/vioif.h @@ -164,6 +164,7 @@ extern "C" { #define VIRTIO_NET_WANTED_FEATURES (VIRTIO_NET_F_CSUM | \ VIRTIO_NET_F_GSO | \ VIRTIO_NET_F_HOST_TSO4 | \ + VIRTIO_NET_F_HOST_TSO6 | \ VIRTIO_NET_F_HOST_ECN | \ VIRTIO_NET_F_MAC | \ VIRTIO_NET_F_MTU) @@ -356,6 +357,7 @@ struct vioif { */ unsigned int vif_tx_csum:1; unsigned int vif_tx_tso4:1; + unsigned int vif_tx_tso6:1; /* * For debugging, it is useful to know whether the MAC address we diff --git a/usr/src/uts/common/sys/dld.h b/usr/src/uts/common/sys/dld.h index 6449f39a35..cf2780d57a 100644 --- a/usr/src/uts/common/sys/dld.h +++ b/usr/src/uts/common/sys/dld.h @@ -434,7 +434,8 @@ typedef struct dld_capab_poll_s { typedef struct dld_capab_lso_s { uint_t lso_flags; /* capability flags */ - uint_t lso_max; /* maximum payload */ + uint_t lso_max_tcpv4; /* maximum TCPv4 payload */ + uint_t lso_max_tcpv6; /* maximum TCPv6 payload */ } dld_capab_lso_t; int dld_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); diff --git a/usr/src/uts/common/sys/mac_provider.h b/usr/src/uts/common/sys/mac_provider.h index b5f0c0c870..8e47f99296 100644 --- a/usr/src/uts/common/sys/mac_provider.h +++ b/usr/src/uts/common/sys/mac_provider.h @@ -119,10 +119,15 @@ typedef struct lso_basic_tcp_ipv4_s { t_uscalar_t lso_max; /* maximum payload */ } lso_basic_tcp_ipv4_t; +typedef struct lso_basic_tcp_ipv6_s { + t_uscalar_t lso_max; /* maximum payload */ +} lso_basic_tcp_ipv6_t; + /* * Currently supported flags for LSO. */ -#define LSO_TX_BASIC_TCP_IPV4 0x01 /* TCP LSO capability */ +#define LSO_TX_BASIC_TCP_IPV4 0x01 /* TCPv4 LSO capability */ +#define LSO_TX_BASIC_TCP_IPV6 0x02 /* TCPv6 LSO capability */ /* * Future LSO capabilities can be added at the end of the mac_capab_lso_t. @@ -135,6 +140,7 @@ typedef struct lso_basic_tcp_ipv4_s { typedef struct mac_capab_lso_s { t_uscalar_t lso_flags; lso_basic_tcp_ipv4_t lso_basic_tcp_ipv4; + lso_basic_tcp_ipv6_t lso_basic_tcp_ipv6; /* Add future lso capabilities here */ } mac_capab_lso_t; |