summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavio Leitner <fbl@sysclose.org>2020-02-14 10:03:36 -0300
committerIlya Maximets <i.maximets@ovn.org>2020-02-26 15:24:15 +0100
commit35b5586ba7ab2d7f53decb978df6bfea4600f6d4 (patch)
tree20405cf429d942ad6338477e47266091bf674f64
parent8c5163fe81ea05313eaefcd61cf036dd3fd2ae07 (diff)
downloadopenvswitch-35b5586ba7ab2d7f53decb978df6bfea4600f6d4.tar.gz
userspace TSO: SCTP checksum offload optional.
Ideally SCTP checksum offload needs be advertised by the NIC when userspace TSO is enabled. However, very few drivers do that and it's not a widely used protocol. So, this patch enables SCTP checksum offload if available, otherwise userspace TSO can still be enabled but SCTP packets will be dropped on NICs without support. Fixes: 29cf9c1b3b9c ("userspace: Add TCP Segmentation Offload support") Signed-off-by: Flavio Leitner <fbl@sysclose.org> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
-rw-r--r--Documentation/topics/userspace-tso.rst7
-rw-r--r--lib/netdev-dpdk.c21
-rw-r--r--lib/netdev-linux.c1
-rw-r--r--lib/netdev-provider.h3
-rw-r--r--lib/netdev.c6
5 files changed, 35 insertions, 3 deletions
diff --git a/Documentation/topics/userspace-tso.rst b/Documentation/topics/userspace-tso.rst
index 9da5d7ef2..0fbac93a5 100644
--- a/Documentation/topics/userspace-tso.rst
+++ b/Documentation/topics/userspace-tso.rst
@@ -91,6 +91,13 @@ The current OvS userspace `TSO` implementation supports flat and VLAN networks
only (i.e. no support for `TSO` over tunneled connection [VxLAN, GRE, IPinIP,
etc.]).
+The NIC driver must support and advertise checksum offload for TCP and UDP.
+However, SCTP is not mandatory because very few drivers advertised support
+and it wasn't a widely used protocol at the moment this feature was introduced
+in Open vSwitch. Currently, if the NIC supports that, then the feature is
+enabled, otherwise TSO can still be enabled but SCTP packets sent to the NIC
+will be dropped.
+
There is no software implementation of TSO, so all ports attached to the
datapath must support TSO or packets using that feature will be dropped
on ports without TSO support. That also means guests using vhost-user
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index ec8be64aa..7ab81864d 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -152,8 +152,10 @@ typedef uint16_t dpdk_port_t;
#define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ)
-/* List of required flags advertised by the hardware that will be
- * used if TSO is enabled. */
+/* List of required flags advertised by the hardware that will be used
+ * if TSO is enabled. Ideally this should include DEV_TX_OFFLOAD_SCTP_CKSUM.
+ * However, very few drivers supports that the moment and SCTP is not a
+ * widely used protocol as TCP and UDP, so it's optional. */
#define DPDK_TX_TSO_OFFLOAD_FLAGS (DEV_TX_OFFLOAD_TCP_TSO \
| DEV_TX_OFFLOAD_TCP_CKSUM \
| DEV_TX_OFFLOAD_UDP_CKSUM \
@@ -423,6 +425,7 @@ enum dpdk_hw_ol_features {
NETDEV_RX_HW_CRC_STRIP = 1 << 1,
NETDEV_RX_HW_SCATTER = 1 << 2,
NETDEV_TX_TSO_OFFLOAD = 1 << 3,
+ NETDEV_TX_SCTP_CHECKSUM_OFFLOAD = 1 << 4,
};
/*
@@ -1006,6 +1009,9 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq)
if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) {
conf.txmode.offloads |= DPDK_TX_TSO_OFFLOAD_FLAGS;
+ if (dev->hw_ol_features & NETDEV_TX_SCTP_CHECKSUM_OFFLOAD) {
+ conf.txmode.offloads |= DEV_TX_OFFLOAD_SCTP_CKSUM;
+ }
}
/* Limit configured rss hash functions to only those supported
@@ -1141,6 +1147,13 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev)
if ((info.tx_offload_capa & tx_tso_offload_capa)
== tx_tso_offload_capa) {
dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD;
+ if (info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) {
+ dev->hw_ol_features |= NETDEV_TX_SCTP_CHECKSUM_OFFLOAD;
+ } else {
+ VLOG_WARN("%s: Tx SCTP checksum offload is not supported, "
+ "SCTP packets sent to this device will be dropped",
+ netdev_get_name(&dev->up));
+ }
} else {
VLOG_WARN("%s: Tx TSO offload is not supported.",
netdev_get_name(&dev->up));
@@ -5116,6 +5129,9 @@ netdev_dpdk_reconfigure(struct netdev *netdev)
netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM;
netdev->ol_flags |= NETDEV_TX_OFFLOAD_UDP_CKSUM;
netdev->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM;
+ if (dev->hw_ol_features & NETDEV_TX_SCTP_CHECKSUM_OFFLOAD) {
+ netdev->ol_flags |= NETDEV_TX_OFFLOAD_SCTP_CKSUM;
+ }
}
dev->tx_q = netdev_dpdk_alloc_txq(netdev->n_txq);
@@ -5258,6 +5274,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)
netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_TSO;
netdev->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM;
netdev->ol_flags |= NETDEV_TX_OFFLOAD_UDP_CKSUM;
+ netdev->ol_flags |= NETDEV_TX_OFFLOAD_SCTP_CKSUM;
netdev->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM;
vhost_unsup_flags = 1ULL << VIRTIO_NET_F_HOST_ECN
| 1ULL << VIRTIO_NET_F_HOST_UFO;
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 85f3a7367..432645601 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -924,6 +924,7 @@ netdev_linux_common_construct(struct netdev *netdev_)
netdev_->ol_flags |= NETDEV_TX_OFFLOAD_TCP_TSO;
netdev_->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM;
netdev_->ol_flags |= NETDEV_TX_OFFLOAD_UDP_CKSUM;
+ netdev_->ol_flags |= NETDEV_TX_OFFLOAD_SCTP_CKSUM;
netdev_->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM;
}
diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
index 00677dc9d..6f509424b 100644
--- a/lib/netdev-provider.h
+++ b/lib/netdev-provider.h
@@ -41,7 +41,8 @@ enum netdev_ol_flags {
NETDEV_TX_OFFLOAD_IPV4_CKSUM = 1 << 0,
NETDEV_TX_OFFLOAD_TCP_CKSUM = 1 << 1,
NETDEV_TX_OFFLOAD_UDP_CKSUM = 1 << 2,
- NETDEV_TX_OFFLOAD_TCP_TSO = 1 << 3,
+ NETDEV_TX_OFFLOAD_SCTP_CKSUM = 1 << 3,
+ NETDEV_TX_OFFLOAD_TCP_TSO = 1 << 4,
};
/* A network device (e.g. an Ethernet device).
diff --git a/lib/netdev.c b/lib/netdev.c
index a55f77961..8c44eee8e 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -814,6 +814,12 @@ netdev_send_prepare_packet(const uint64_t netdev_flags,
VLOG_ERR_BUF(errormsg, "No UDP checksum support");
return false;
}
+ } else if (dp_packet_hwol_l4_is_sctp(packet)) {
+ if (!(netdev_flags & NETDEV_TX_OFFLOAD_SCTP_CKSUM)) {
+ /* Fall back to SCTP csum in software. */
+ VLOG_ERR_BUF(errormsg, "No SCTP checksum support");
+ return false;
+ }
} else {
VLOG_ERR_BUF(errormsg, "No L4 checksum support: mask: %"PRIu64,
l4_mask);