2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-01 06:45:17 +00:00

userspace: Enable TSO support for non-DPDK.

This patch enables TSO support for non-DPDK use cases, and
also add check-system-tso testsuite. Before TSO, we have to
disable checksum offload, allowing the kernel to calculate the
TCP/UDP packet checsum. With TSO, we can skip the checksum
validation by enabling checksum offload, and with large packet
size, we see better performance.

Consider container to container use cases:
  iperf3 -c (ns0) -> veth peer -> OVS -> veth peer -> iperf3 -s (ns1)
And I got around 6Gbps, similar to TSO with DPDK-enabled.

Acked-by: Flavio Leitner <fbl@sysclose.org>
Acked-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: William Tu <u9012063@gmail.com>
This commit is contained in:
William Tu
2020-03-24 15:10:50 -07:00
parent c101cd4171
commit 29bb3093eb
7 changed files with 340 additions and 325 deletions

View File

@@ -192,10 +192,8 @@ dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom)
sizeof(struct dp_packet) -
offsetof(struct dp_packet, l2_pad_size));
#ifdef DPDK_NETDEV
new_buffer->mbuf.ol_flags = buffer->mbuf.ol_flags;
new_buffer->mbuf.ol_flags &= ~DPDK_MBUF_NON_OFFLOADING_FLAGS;
#endif
*dp_packet_ol_flags_ptr(new_buffer) = *dp_packet_ol_flags_ptr(buffer);
*dp_packet_ol_flags_ptr(new_buffer) &= DP_PACKET_OL_SUPPORTED_MASK;
if (dp_packet_rss_valid(buffer)) {
dp_packet_set_rss_hash(new_buffer, dp_packet_get_rss_hash(buffer));

View File

@@ -48,18 +48,62 @@ enum OVS_PACKED_ENUM dp_packet_source {
#define DP_PACKET_CONTEXT_SIZE 64
#ifndef DPDK_NETDEV
#ifdef DPDK_NETDEV
#define DEF_OL_FLAG(NAME, DPDK_DEF, GENERIC_DEF) NAME = DPDK_DEF
#else
#define DEF_OL_FLAG(NAME, DPDK_DEF, GENERIC_DEF) NAME = GENERIC_DEF
#endif
/* Bit masks for the 'ol_flags' member of the 'dp_packet' structure. */
enum dp_packet_offload_mask {
DP_PACKET_OL_RSS_HASH_MASK = 0x1, /* Is the 'rss_hash' valid? */
DP_PACKET_OL_FLOW_MARK_MASK = 0x2, /* Is the 'flow_mark' valid? */
/* Value 0 is not used. */
/* Is the 'rss_hash' valid? */
DEF_OL_FLAG(DP_PACKET_OL_RSS_HASH, PKT_RX_RSS_HASH, 0x1),
/* Is the 'flow_mark' valid? */
DEF_OL_FLAG(DP_PACKET_OL_FLOW_MARK, PKT_RX_FDIR_ID, 0x2),
/* Bad L4 checksum in the packet. */
DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_BAD, PKT_RX_L4_CKSUM_BAD, 0x4),
/* Bad IP checksum in the packet. */
DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_BAD, PKT_RX_IP_CKSUM_BAD, 0x8),
/* Valid L4 checksum in the packet. */
DEF_OL_FLAG(DP_PACKET_OL_RX_L4_CKSUM_GOOD, PKT_RX_L4_CKSUM_GOOD, 0x10),
/* Valid IP checksum in the packet. */
DEF_OL_FLAG(DP_PACKET_OL_RX_IP_CKSUM_GOOD, PKT_RX_IP_CKSUM_GOOD, 0x20),
/* TCP Segmentation Offload. */
DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_SEG, PKT_TX_TCP_SEG, 0x40),
/* Offloaded packet is IPv4. */
DEF_OL_FLAG(DP_PACKET_OL_TX_IPV4, PKT_TX_IPV4, 0x80),
/* Offloaded packet is IPv6. */
DEF_OL_FLAG(DP_PACKET_OL_TX_IPV6, PKT_TX_IPV6, 0x100),
/* Offload TCP checksum. */
DEF_OL_FLAG(DP_PACKET_OL_TX_TCP_CKSUM, PKT_TX_TCP_CKSUM, 0x200),
/* Offload UDP checksum. */
DEF_OL_FLAG(DP_PACKET_OL_TX_UDP_CKSUM, PKT_TX_UDP_CKSUM, 0x400),
/* Offload SCTP checksum. */
DEF_OL_FLAG(DP_PACKET_OL_TX_SCTP_CKSUM, PKT_TX_SCTP_CKSUM, 0x800),
/* Adding new field requires adding to DP_PACKET_OL_SUPPORTED_MASK. */
};
#else
/* DPDK mbuf ol_flags that are not really an offload flags. These are mostly
* related to mbuf memory layout and OVS should not touch/clear them. */
#define DPDK_MBUF_NON_OFFLOADING_FLAGS (EXT_ATTACHED_MBUF | \
IND_ATTACHED_MBUF)
#endif
#define DP_PACKET_OL_SUPPORTED_MASK (DP_PACKET_OL_RSS_HASH | \
DP_PACKET_OL_FLOW_MARK | \
DP_PACKET_OL_RX_L4_CKSUM_BAD | \
DP_PACKET_OL_RX_IP_CKSUM_BAD | \
DP_PACKET_OL_RX_L4_CKSUM_GOOD | \
DP_PACKET_OL_RX_IP_CKSUM_GOOD | \
DP_PACKET_OL_TX_TCP_SEG | \
DP_PACKET_OL_TX_IPV4 | \
DP_PACKET_OL_TX_IPV6 | \
DP_PACKET_OL_TX_TCP_CKSUM | \
DP_PACKET_OL_TX_UDP_CKSUM | \
DP_PACKET_OL_TX_SCTP_CKSUM)
#define DP_PACKET_OL_TX_L4_MASK (DP_PACKET_OL_TX_TCP_CKSUM | \
DP_PACKET_OL_TX_UDP_CKSUM | \
DP_PACKET_OL_TX_SCTP_CKSUM)
#define DP_PACKET_OL_RX_IP_CKSUM_MASK (DP_PACKET_OL_RX_IP_CKSUM_GOOD | \
DP_PACKET_OL_RX_IP_CKSUM_BAD)
#define DP_PACKET_OL_RX_L4_CKSUM_MASK (DP_PACKET_OL_RX_L4_CKSUM_GOOD | \
DP_PACKET_OL_RX_L4_CKSUM_BAD)
/* Buffer for holding packet data. A dp_packet is automatically reallocated
* as necessary if it grows too large for the available memory.
@@ -450,6 +494,45 @@ dp_packet_get_nd_payload(const struct dp_packet *b)
? (const char *)dp_packet_l4(b) + ND_MSG_LEN : NULL;
}
#ifdef DPDK_NETDEV
static inline uint64_t *
dp_packet_ol_flags_ptr(const struct dp_packet *b)
{
return CONST_CAST(uint64_t *, &b->mbuf.ol_flags);
}
static inline uint32_t *
dp_packet_rss_ptr(const struct dp_packet *b)
{
return CONST_CAST(uint32_t *, &b->mbuf.hash.rss);
}
static inline uint32_t *
dp_packet_flow_mark_ptr(const struct dp_packet *b)
{
return CONST_CAST(uint32_t *, &b->mbuf.hash.fdir.hi);
}
#else
static inline uint32_t *
dp_packet_ol_flags_ptr(const struct dp_packet *b)
{
return CONST_CAST(uint32_t *, &b->ol_flags);
}
static inline uint32_t *
dp_packet_rss_ptr(const struct dp_packet *b)
{
return CONST_CAST(uint32_t *, &b->rss_hash);
}
static inline uint32_t *
dp_packet_flow_mark_ptr(const struct dp_packet *b)
{
return CONST_CAST(uint32_t *, &b->flow_mark);
}
#endif
#ifdef DPDK_NETDEV
BUILD_ASSERT_DECL(offsetof(struct dp_packet, mbuf) == 0);
@@ -521,168 +604,6 @@ dp_packet_set_allocated(struct dp_packet *b, uint16_t s)
b->mbuf.buf_len = s;
}
/* Returns 'true' if packet 'b' is marked for TCP segmentation offloading. */
static inline bool
dp_packet_hwol_is_tso(const struct dp_packet *b)
{
return !!(b->mbuf.ol_flags & PKT_TX_TCP_SEG);
}
/* Returns 'true' if packet 'b' is marked for IPv4 checksum offloading. */
static inline bool
dp_packet_hwol_is_ipv4(const struct dp_packet *b)
{
return !!(b->mbuf.ol_flags & PKT_TX_IPV4);
}
/* Returns the L4 cksum offload bitmask. */
static inline uint64_t
dp_packet_hwol_l4_mask(const struct dp_packet *b)
{
return b->mbuf.ol_flags & PKT_TX_L4_MASK;
}
/* Returns 'true' if packet 'b' is marked for TCP checksum offloading. */
static inline bool
dp_packet_hwol_l4_is_tcp(const struct dp_packet *b)
{
return (b->mbuf.ol_flags & PKT_TX_L4_MASK) == PKT_TX_TCP_CKSUM;
}
/* Returns 'true' if packet 'b' is marked for UDP checksum offloading. */
static inline bool
dp_packet_hwol_l4_is_udp(struct dp_packet *b)
{
return (b->mbuf.ol_flags & PKT_TX_L4_MASK) == PKT_TX_UDP_CKSUM;
}
/* Returns 'true' if packet 'b' is marked for SCTP checksum offloading. */
static inline bool
dp_packet_hwol_l4_is_sctp(struct dp_packet *b)
{
return (b->mbuf.ol_flags & PKT_TX_L4_MASK) == PKT_TX_SCTP_CKSUM;
}
/* Mark packet 'b' for IPv4 checksum offloading. */
static inline void
dp_packet_hwol_set_tx_ipv4(struct dp_packet *b)
{
b->mbuf.ol_flags |= PKT_TX_IPV4;
}
/* Mark packet 'b' for IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_tx_ipv6(struct dp_packet *b)
{
b->mbuf.ol_flags |= PKT_TX_IPV6;
}
/* Mark packet 'b' for TCP checksum offloading. It implies that either
* the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_csum_tcp(struct dp_packet *b)
{
b->mbuf.ol_flags |= PKT_TX_TCP_CKSUM;
}
/* Mark packet 'b' for UDP checksum offloading. It implies that either
* the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_csum_udp(struct dp_packet *b)
{
b->mbuf.ol_flags |= PKT_TX_UDP_CKSUM;
}
/* Mark packet 'b' for SCTP checksum offloading. It implies that either
* the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_csum_sctp(struct dp_packet *b)
{
b->mbuf.ol_flags |= PKT_TX_SCTP_CKSUM;
}
/* Mark packet 'b' for TCP segmentation offloading. It implies that
* either the packet 'b' is marked for IPv4 or IPv6 checksum offloading
* and also for TCP checksum offloading. */
static inline void
dp_packet_hwol_set_tcp_seg(struct dp_packet *b)
{
b->mbuf.ol_flags |= PKT_TX_TCP_SEG;
}
/* Returns the RSS hash of the packet 'p'. Note that the returned value is
* correct only if 'dp_packet_rss_valid(p)' returns true */
static inline uint32_t
dp_packet_get_rss_hash(const struct dp_packet *p)
{
return p->mbuf.hash.rss;
}
static inline void
dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash)
{
p->mbuf.hash.rss = hash;
p->mbuf.ol_flags |= PKT_RX_RSS_HASH;
}
static inline bool
dp_packet_rss_valid(const struct dp_packet *p)
{
return p->mbuf.ol_flags & PKT_RX_RSS_HASH;
}
static inline void
dp_packet_reset_offload(struct dp_packet *p)
{
p->mbuf.ol_flags &= DPDK_MBUF_NON_OFFLOADING_FLAGS;
}
static inline bool
dp_packet_ip_checksum_valid(const struct dp_packet *p)
{
return (p->mbuf.ol_flags & PKT_RX_IP_CKSUM_MASK) ==
PKT_RX_IP_CKSUM_GOOD;
}
static inline bool
dp_packet_ip_checksum_bad(const struct dp_packet *p)
{
return (p->mbuf.ol_flags & PKT_RX_IP_CKSUM_MASK) ==
PKT_RX_IP_CKSUM_BAD;
}
static inline bool
dp_packet_l4_checksum_valid(const struct dp_packet *p)
{
return (p->mbuf.ol_flags & PKT_RX_L4_CKSUM_MASK) ==
PKT_RX_L4_CKSUM_GOOD;
}
static inline bool
dp_packet_l4_checksum_bad(const struct dp_packet *p)
{
return (p->mbuf.ol_flags & PKT_RX_L4_CKSUM_MASK) ==
PKT_RX_L4_CKSUM_BAD;
}
static inline bool
dp_packet_has_flow_mark(const struct dp_packet *p, uint32_t *mark)
{
if (p->mbuf.ol_flags & PKT_RX_FDIR_ID) {
*mark = p->mbuf.hash.fdir.hi;
return true;
}
return false;
}
static inline void
dp_packet_set_flow_mark(struct dp_packet *p, uint32_t mark)
{
p->mbuf.hash.fdir.hi = mark;
p->mbuf.ol_flags |= PKT_RX_FDIR_ID;
}
#else /* DPDK_NETDEV */
static inline void
@@ -739,151 +660,6 @@ dp_packet_set_allocated(struct dp_packet *b, uint16_t s)
b->allocated_ = s;
}
/* There are no implementation when not DPDK enabled datapath. */
static inline bool
dp_packet_hwol_is_tso(const struct dp_packet *b OVS_UNUSED)
{
return false;
}
/* There are no implementation when not DPDK enabled datapath. */
static inline bool
dp_packet_hwol_is_ipv4(const struct dp_packet *b OVS_UNUSED)
{
return false;
}
/* There are no implementation when not DPDK enabled datapath. */
static inline uint64_t
dp_packet_hwol_l4_mask(const struct dp_packet *b OVS_UNUSED)
{
return 0;
}
/* There are no implementation when not DPDK enabled datapath. */
static inline bool
dp_packet_hwol_l4_is_tcp(const struct dp_packet *b OVS_UNUSED)
{
return false;
}
/* There are no implementation when not DPDK enabled datapath. */
static inline bool
dp_packet_hwol_l4_is_udp(const struct dp_packet *b OVS_UNUSED)
{
return false;
}
/* There are no implementation when not DPDK enabled datapath. */
static inline bool
dp_packet_hwol_l4_is_sctp(const struct dp_packet *b OVS_UNUSED)
{
return false;
}
/* There are no implementation when not DPDK enabled datapath. */
static inline void
dp_packet_hwol_set_tx_ipv4(struct dp_packet *b OVS_UNUSED)
{
}
/* There are no implementation when not DPDK enabled datapath. */
static inline void
dp_packet_hwol_set_tx_ipv6(struct dp_packet *b OVS_UNUSED)
{
}
/* There are no implementation when not DPDK enabled datapath. */
static inline void
dp_packet_hwol_set_csum_tcp(struct dp_packet *b OVS_UNUSED)
{
}
/* There are no implementation when not DPDK enabled datapath. */
static inline void
dp_packet_hwol_set_csum_udp(struct dp_packet *b OVS_UNUSED)
{
}
/* There are no implementation when not DPDK enabled datapath. */
static inline void
dp_packet_hwol_set_csum_sctp(struct dp_packet *b OVS_UNUSED)
{
}
/* There are no implementation when not DPDK enabled datapath. */
static inline void
dp_packet_hwol_set_tcp_seg(struct dp_packet *b OVS_UNUSED)
{
}
/* Returns the RSS hash of the packet 'p'. Note that the returned value is
* correct only if 'dp_packet_rss_valid(p)' returns true */
static inline uint32_t
dp_packet_get_rss_hash(const struct dp_packet *p)
{
return p->rss_hash;
}
static inline void
dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash)
{
p->rss_hash = hash;
p->ol_flags |= DP_PACKET_OL_RSS_HASH_MASK;
}
static inline bool
dp_packet_rss_valid(const struct dp_packet *p)
{
return p->ol_flags & DP_PACKET_OL_RSS_HASH_MASK;
}
static inline void
dp_packet_reset_offload(struct dp_packet *p)
{
p->ol_flags = 0;
}
static inline bool
dp_packet_ip_checksum_valid(const struct dp_packet *p OVS_UNUSED)
{
return false;
}
static inline bool
dp_packet_ip_checksum_bad(const struct dp_packet *p OVS_UNUSED)
{
return false;
}
static inline bool
dp_packet_l4_checksum_valid(const struct dp_packet *p OVS_UNUSED)
{
return false;
}
static inline bool
dp_packet_l4_checksum_bad(const struct dp_packet *p OVS_UNUSED)
{
return false;
}
static inline bool
dp_packet_has_flow_mark(const struct dp_packet *p, uint32_t *mark)
{
if (p->ol_flags & DP_PACKET_OL_FLOW_MARK_MASK) {
*mark = p->flow_mark;
return true;
}
return false;
}
static inline void
dp_packet_set_flow_mark(struct dp_packet *p, uint32_t mark)
{
p->flow_mark = mark;
p->ol_flags |= DP_PACKET_OL_FLOW_MARK_MASK;
}
#endif /* DPDK_NETDEV */
static inline void
@@ -1112,6 +888,58 @@ dp_packet_batch_reset_cutlen(struct dp_packet_batch *batch)
}
}
/* Returns the RSS hash of the packet 'p'. Note that the returned value is
* correct only if 'dp_packet_rss_valid(p)' returns 'true'. */
static inline uint32_t
dp_packet_get_rss_hash(const struct dp_packet *p)
{
return *dp_packet_rss_ptr(p);
}
static inline void
dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash)
{
*dp_packet_rss_ptr(p) = hash;
*dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RSS_HASH;
}
static inline bool
dp_packet_rss_valid(const struct dp_packet *p)
{
return *dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RSS_HASH;
}
static inline void
dp_packet_reset_offload(struct dp_packet *p)
{
*dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_SUPPORTED_MASK;
}
static inline bool
dp_packet_has_flow_mark(const struct dp_packet *p, uint32_t *mark)
{
if (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_FLOW_MARK) {
*mark = *dp_packet_flow_mark_ptr(p);
return true;
}
return false;
}
static inline void
dp_packet_set_flow_mark(struct dp_packet *p, uint32_t mark)
{
*dp_packet_flow_mark_ptr(p) = mark;
*dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_FLOW_MARK;
}
/* Returns the L4 cksum offload bitmask. */
static inline uint64_t
dp_packet_hwol_l4_mask(const struct dp_packet *b)
{
return *dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK;
}
/* Return true if the packet 'b' requested L4 checksum offload. */
static inline bool
dp_packet_hwol_tx_l4_checksum(const struct dp_packet *b)
@@ -1119,6 +947,119 @@ dp_packet_hwol_tx_l4_checksum(const struct dp_packet *b)
return !!dp_packet_hwol_l4_mask(b);
}
/* Returns 'true' if packet 'b' is marked for TCP segmentation offloading. */
static inline bool
dp_packet_hwol_is_tso(const struct dp_packet *b)
{
return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_TCP_SEG);
}
/* Returns 'true' if packet 'b' is marked for IPv4 checksum offloading. */
static inline bool
dp_packet_hwol_is_ipv4(const struct dp_packet *b)
{
return !!(*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_IPV4);
}
/* Returns 'true' if packet 'b' is marked for TCP checksum offloading. */
static inline bool
dp_packet_hwol_l4_is_tcp(const struct dp_packet *b)
{
return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) ==
DP_PACKET_OL_TX_TCP_CKSUM;
}
/* Returns 'true' if packet 'b' is marked for UDP checksum offloading. */
static inline bool
dp_packet_hwol_l4_is_udp(struct dp_packet *b)
{
return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) ==
DP_PACKET_OL_TX_UDP_CKSUM;
}
/* Returns 'true' if packet 'b' is marked for SCTP checksum offloading. */
static inline bool
dp_packet_hwol_l4_is_sctp(struct dp_packet *b)
{
return (*dp_packet_ol_flags_ptr(b) & DP_PACKET_OL_TX_L4_MASK) ==
DP_PACKET_OL_TX_SCTP_CKSUM;
}
/* Mark packet 'b' for IPv4 checksum offloading. */
static inline void
dp_packet_hwol_set_tx_ipv4(struct dp_packet *b)
{
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_IPV4;
}
/* Mark packet 'b' for IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_tx_ipv6(struct dp_packet *b)
{
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_IPV6;
}
/* Mark packet 'b' for TCP checksum offloading. It implies that either
* the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_csum_tcp(struct dp_packet *b)
{
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TCP_CKSUM;
}
/* Mark packet 'b' for UDP checksum offloading. It implies that either
* the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_csum_udp(struct dp_packet *b)
{
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_UDP_CKSUM;
}
/* Mark packet 'b' for SCTP checksum offloading. It implies that either
* the packet 'b' is marked for IPv4 or IPv6 checksum offloading. */
static inline void
dp_packet_hwol_set_csum_sctp(struct dp_packet *b)
{
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_SCTP_CKSUM;
}
/* Mark packet 'b' for TCP segmentation offloading. It implies that
* either the packet 'b' is marked for IPv4 or IPv6 checksum offloading
* and also for TCP checksum offloading. */
static inline void
dp_packet_hwol_set_tcp_seg(struct dp_packet *b)
{
*dp_packet_ol_flags_ptr(b) |= DP_PACKET_OL_TX_TCP_SEG;
}
static inline bool
dp_packet_ip_checksum_valid(const struct dp_packet *p)
{
return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) ==
DP_PACKET_OL_RX_IP_CKSUM_GOOD;
}
static inline bool
dp_packet_ip_checksum_bad(const struct dp_packet *p)
{
return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_IP_CKSUM_MASK) ==
DP_PACKET_OL_RX_IP_CKSUM_BAD;
}
static inline bool
dp_packet_l4_checksum_valid(const struct dp_packet *p)
{
return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) ==
DP_PACKET_OL_RX_L4_CKSUM_GOOD;
}
static inline bool
dp_packet_l4_checksum_bad(const struct dp_packet *p)
{
return (*dp_packet_ol_flags_ptr(p) & DP_PACKET_OL_RX_L4_CKSUM_MASK) ==
DP_PACKET_OL_RX_L4_CKSUM_BAD;
}
#ifdef __cplusplus
}
#endif

View File

@@ -34,13 +34,8 @@ userspace_tso_init(const struct smap *ovs_other_config)
static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
if (ovsthread_once_start(&once)) {
#ifdef DPDK_NETDEV
VLOG_INFO("Userspace TCP Segmentation Offloading support enabled");
userspace_tso = true;
#else
VLOG_WARN("Userspace TCP Segmentation Offloading can not be enabled"
"since OVS is built without DPDK support.");
#endif
ovsthread_once_done(&once);
}
}

3
tests/.gitignore vendored
View File

@@ -24,6 +24,9 @@
/system-userspace-testsuite
/system-userspace-testsuite.dir/
/system-userspace-testsuite.log
/system-tso-testsuite
/system-tso-testsuite.dir/
/system-tso-testsuite.log
/system-offloads-testsuite
/system-offloads-testsuite.dir/
/system-offloads-testsuite.log

View File

@@ -4,6 +4,7 @@ EXTRA_DIST += \
$(SYSTEM_TESTSUITE_AT) \
$(SYSTEM_KMOD_TESTSUITE_AT) \
$(SYSTEM_USERSPACE_TESTSUITE_AT) \
$(SYSTEM_TSO_TESTSUITE_AT) \
$(SYSTEM_AFXDP_TESTSUITE_AT) \
$(SYSTEM_OFFLOADS_TESTSUITE_AT) \
$(SYSTEM_DPDK_TESTSUITE_AT) \
@@ -11,6 +12,7 @@ EXTRA_DIST += \
$(TESTSUITE) \
$(SYSTEM_KMOD_TESTSUITE) \
$(SYSTEM_USERSPACE_TESTSUITE) \
$(SYSTEM_TSO_TESTSUITE) \
$(SYSTEM_AFXDP_TESTSUITE) \
$(SYSTEM_OFFLOADS_TESTSUITE) \
$(SYSTEM_DPDK_TESTSUITE) \
@@ -154,6 +156,10 @@ SYSTEM_USERSPACE_TESTSUITE_AT = \
tests/system-userspace-macros.at \
tests/system-userspace-packet-type-aware.at
SYSTEM_TSO_TESTSUITE_AT = \
tests/system-tso-testsuite.at \
tests/system-tso-macros.at
SYSTEM_AFXDP_TESTSUITE_AT = \
tests/system-userspace-macros.at \
tests/system-afxdp-testsuite.at \
@@ -183,6 +189,7 @@ TESTSUITE = $(srcdir)/tests/testsuite
TESTSUITE_PATCH = $(srcdir)/tests/testsuite.patch
SYSTEM_KMOD_TESTSUITE = $(srcdir)/tests/system-kmod-testsuite
SYSTEM_USERSPACE_TESTSUITE = $(srcdir)/tests/system-userspace-testsuite
SYSTEM_TSO_TESTSUITE = $(srcdir)/tests/system-tso-testsuite
SYSTEM_AFXDP_TESTSUITE = $(srcdir)/tests/system-afxdp-testsuite
SYSTEM_OFFLOADS_TESTSUITE = $(srcdir)/tests/system-offloads-testsuite
SYSTEM_DPDK_TESTSUITE = $(srcdir)/tests/system-dpdk-testsuite
@@ -296,6 +303,12 @@ check-offloads-valgrind: all $(valgrind_wrappers) $(check_DATA)
@echo '----------------------------------------------------------------------'
@echo 'Valgrind output can be found in tests/system-offloads-testsuite.dir/*/valgrind.*'
@echo '----------------------------------------------------------------------'
check-tso-valgrind: all $(valgrind_wrappers) $(check_DATA)
$(SHELL) '$(SYSTEM_TSO_TESTSUITE)' -C tests VALGRIND='$(VALGRIND)' AUTOTEST_PATH='tests/valgrind:$(AUTOTEST_PATH)' -d $(TESTSUITEFLAGS) -j1
@echo
@echo '----------------------------------------------------------------------'
@echo 'Valgrind output can be found in tests/system-tso-testsuite.dir/*/valgrind.*'
@echo '----------------------------------------------------------------------'
check-helgrind: all $(valgrind_wrappers) $(check_DATA)
-$(SHELL) '$(TESTSUITE)' -C tests CHECK_VALGRIND=true VALGRIND='$(HELGRIND)' AUTOTEST_PATH='tests/valgrind:$(AUTOTEST_PATH)' -d $(TESTSUITEFLAGS)
@@ -326,6 +339,10 @@ check-system-userspace: all
set $(SHELL) '$(SYSTEM_USERSPACE_TESTSUITE)' -C tests AUTOTEST_PATH='$(AUTOTEST_PATH)'; \
"$$@" $(TESTSUITEFLAGS) -j1 || (test X'$(RECHECK)' = Xyes && "$$@" --recheck)
check-system-tso: all
set $(SHELL) '$(SYSTEM_TSO_TESTSUITE)' -C tests AUTOTEST_PATH='$(AUTOTEST_PATH)'; \
"$$@" $(TESTSUITEFLAGS) -j1 || (test X'$(RECHECK)' = Xyes && "$$@" --recheck)
check-afxdp: all
set $(SHELL) '$(SYSTEM_AFXDP_TESTSUITE)' -C tests AUTOTEST_PATH='$(AUTOTEST_PATH)' $(TESTSUITEFLAGS) -j1; \
"$$@" || (test X'$(RECHECK)' = Xyes && "$$@" --recheck)
@@ -367,6 +384,10 @@ $(SYSTEM_USERSPACE_TESTSUITE): package.m4 $(SYSTEM_TESTSUITE_AT) $(SYSTEM_USERSP
$(AM_V_GEN)$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
$(AM_V_at)mv $@.tmp $@
$(SYSTEM_TSO_TESTSUITE): package.m4 $(SYSTEM_TESTSUITE_AT) $(SYSTEM_TSO_TESTSUITE_AT) $(COMMON_MACROS_AT)
$(AM_V_GEN)$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
$(AM_V_at)mv $@.tmp $@
$(SYSTEM_AFXDP_TESTSUITE): package.m4 $(SYSTEM_TESTSUITE_AT) $(SYSTEM_AFXDP_TESTSUITE_AT) $(COMMON_MACROS_AT)
$(AM_V_GEN)$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
$(AM_V_at)mv $@.tmp $@

View File

@@ -0,0 +1,31 @@
# _ADD_BR([name])
#
# Expands into the proper ovs-vsctl commands to create a bridge with the
# appropriate type and properties
m4_define([_ADD_BR], [[add-br $1 -- set Bridge $1 datapath_type="netdev" protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15 fail-mode=secure ]])
# OVS_TRAFFIC_VSWITCHD_START([vsctl-args], [vsctl-output], [=override])
#
# Creates a database and starts ovsdb-server, starts ovs-vswitchd
# connected to that database, calls ovs-vsctl to create a bridge named
# br0 with predictable settings, passing 'vsctl-args' as additional
# commands to ovs-vsctl. If 'vsctl-args' causes ovs-vsctl to provide
# output (e.g. because it includes "create" commands) then 'vsctl-output'
# specifies the expected output after filtering through uuidfilt.
m4_define([OVS_TRAFFIC_VSWITCHD_START],
[
OVS_WAIT_WHILE([ip link show ovs-netdev])
_OVS_VSWITCHD_START([--disable-system])
dnl Add bridges, ports, etc.
OVS_WAIT_WHILE([ip link show br0])
AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:userspace-tso-enable=true])
AT_CHECK([ovs-vsctl -- _ADD_BR([br0]) -- $1 m4_if([$2], [], [], [| uuidfilt])], [0], [$2])
])
# CONFIGURE_VETH_OFFLOADS([VETH])
#
# Enable TCP segmentation offload and scatter-gather for veths.
m4_define([CONFIGURE_VETH_OFFLOADS],
[AT_CHECK([ethtool -K $1 sg on], [0], [ignore], [ignore])]
[AT_CHECK([ethtool -K $1 tso on], [0], [ignore], [ignore])]
)

View File

@@ -0,0 +1,26 @@
AT_INIT
AT_COPYRIGHT([Copyright (c) 2020 VMware, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.])
m4_ifdef([AT_COLOR_TESTS], [AT_COLOR_TESTS])
m4_include([tests/ovs-macros.at])
m4_include([tests/ovsdb-macros.at])
m4_include([tests/ofproto-macros.at])
m4_include([tests/system-common-macros.at])
m4_include([tests/system-userspace-macros.at])
m4_include([tests/system-tso-macros.at])
m4_include([tests/system-traffic.at])