From 2c0a4f407f565d8dd33ff3a9fada346860d30ad2 Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Thu, 29 Jun 2017 09:30:15 -0400 Subject: TCP/UDP checksum offload API Change-Id: I2cb6ce4e29813f6602b14e6e61713fb381fbcef8 Signed-off-by: Dave Barach --- src/plugins/dpdk/device/device.c | 41 ++++++++++++++++++++++++++++++++++++++++ src/plugins/dpdk/device/dpdk.h | 3 +++ src/plugins/dpdk/device/init.c | 8 ++++++++ 3 files changed, 52 insertions(+) (limited to 'src/plugins/dpdk/device') diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index 8801bfd3a25..c755060d658 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -335,6 +335,37 @@ dpdk_buffer_recycle (vlib_main_t * vm, vlib_node_runtime_t * node, vec_add1 (dm->recycle[my_cpu], bi); } +static_always_inline void +dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b, + struct rte_mbuf *mb) +{ + u32 ip_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM; + u32 tcp_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM; + u32 udp_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM; + int is_ip4 = b->flags & VNET_BUFFER_F_IS_IP4; + u64 ol_flags; + + /* Is there any work for us? */ + if (PREDICT_TRUE ((ip_cksum | tcp_cksum | udp_cksum) == 0)) + return; + + mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data; + mb->l3_len = vnet_buffer (b)->l4_hdr_offset - + vnet_buffer (b)->l3_hdr_offset; + mb->outer_l3_len = 0; + mb->outer_l2_len = 0; + ol_flags = is_ip4 ? PKT_TX_IPV4 : PKT_TX_IPV6; + ol_flags |= ip_cksum ? PKT_TX_IP_CKSUM : 0; + ol_flags |= tcp_cksum ? PKT_TX_TCP_CKSUM : 0; + ol_flags |= udp_cksum ? PKT_TX_UDP_CKSUM : 0; + mb->ol_flags |= ol_flags; + + /* we are trying to help compiler here by using local ol_flags with known + state of all flags */ + if (xd->flags & DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM) + rte_net_intel_cksum_flags_prepare (mb, ol_flags); +} + /* * Transmits the packets on the frame to the interface associated with the * node. It first copies packets on the frame to a tx_vector containing the @@ -455,6 +486,15 @@ dpdk_interface_tx (vlib_main_t * vm, mb2 = rte_mbuf_from_vlib_buffer (b2); mb3 = rte_mbuf_from_vlib_buffer (b3); + if (PREDICT_FALSE ((xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD) && + (or_flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM))) + { + dpdk_buffer_tx_offload (xd, b0, mb0); + dpdk_buffer_tx_offload (xd, b1, mb1); + dpdk_buffer_tx_offload (xd, b2, mb2); + dpdk_buffer_tx_offload (xd, b3, mb3); + } + if (PREDICT_FALSE (or_flags & VLIB_BUFFER_RECYCLE)) { dpdk_buffer_recycle (vm, node, b0, bi0, &mb0); @@ -521,6 +561,7 @@ dpdk_interface_tx (vlib_main_t * vm, dpdk_validate_rte_mbuf (vm, b0, 1); mb0 = rte_mbuf_from_vlib_buffer (b0); + dpdk_buffer_tx_offload (xd, b0, mb0); dpdk_buffer_recycle (vm, node, b0, bi0, &mb0); if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE)) diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index 55f63b37307..29a2c760e8d 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -176,6 +177,8 @@ typedef struct #define DPDK_DEVICE_FLAG_HQOS (1 << 6) #define DPDK_DEVICE_FLAG_BOND_SLAVE (1 << 7) #define DPDK_DEVICE_FLAG_BOND_SLAVE_UP (1 << 8) +#define DPDK_DEVICE_FLAG_TX_OFFLOAD (1 << 9) +#define DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM (1 << 10) u16 nb_tx_desc; CLIB_CACHE_LINE_ALIGN_MARK (cacheline1); diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 7ca3d358403..8a7080352e7 100755 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -351,6 +351,11 @@ dpdk_lib_init (dpdk_main_t * dm) case VNET_DPDK_PMD_IGB: case VNET_DPDK_PMD_IXGBE: case VNET_DPDK_PMD_I40E: + xd->port_type = port_type_from_speed_capa (&dev_info); + xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD | + DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM; + + break; case VNET_DPDK_PMD_CXGBE: case VNET_DPDK_PMD_MLX4: case VNET_DPDK_PMD_MLX5: @@ -575,6 +580,9 @@ dpdk_lib_init (dpdk_main_t * dm) hi = vnet_get_hw_interface (dm->vnet_main, xd->hw_if_index); + if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD) + hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD; + dpdk_device_setup (xd); if (vec_len (xd->errors)) -- cgit 1.2.3-korg