summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@fingolfin.org>2020-04-01 15:30:20 +0000
committerRobert Mustacchi <rm@fingolfin.org>2020-04-08 04:07:18 -0700
commit62366fbbe8edca853fee6c14327d822239ba914f (patch)
treec8a05f17464a8302fc2870a8a2c47b1625b9b9f8
parentd240edaf609c558d5a1f981b09a577823b54fae2 (diff)
downloadillumos-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.h3
-rw-r--r--usr/src/uts/common/inet/ip/ip_if.c10
-rw-r--r--usr/src/uts/common/inet/ip/ip_output.c3
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c6
-rw-r--r--usr/src/uts/common/io/dld/dld_proto.c29
-rw-r--r--usr/src/uts/common/io/vioif/vioif.c21
-rw-r--r--usr/src/uts/common/io/vioif/vioif.h2
-rw-r--r--usr/src/uts/common/sys/dld.h3
-rw-r--r--usr/src/uts/common/sys/mac_provider.h8
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;