diff options
-rw-r--r-- | src/plugins/dpdk/device/device.c | 11 | ||||
-rw-r--r-- | src/plugins/dpdk/device/dpdk.h | 4 | ||||
-rw-r--r-- | src/plugins/dpdk/device/init.c | 30 |
3 files changed, 44 insertions, 1 deletions
diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c index 8778d71cd7a..cb0448fa503 100644 --- a/src/plugins/dpdk/device/device.c +++ b/src/plugins/dpdk/device/device.c @@ -226,10 +226,11 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b, 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; + u32 tso = b->flags & VNET_BUFFER_F_GSO; u64 ol_flags; /* Is there any work for us? */ - if (PREDICT_TRUE ((ip_cksum | tcp_cksum | udp_cksum) == 0)) + if (PREDICT_TRUE ((ip_cksum | tcp_cksum | udp_cksum | tso) == 0)) return; mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data; @@ -241,6 +242,14 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b, 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; + ol_flags |= tso ? (tcp_cksum ? PKT_TX_TCP_SEG : PKT_TX_UDP_SEG) : 0; + + if (tso) + { + mb->l4_len = vnet_buffer2 (b)->gso_l4_hdr_sz; + mb->tso_segsz = vnet_buffer2 (b)->gso_size; + } + mb->ol_flags |= ol_flags; /* we are trying to help compiler here by using local ol_flags with known diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index 0ec4ec3f28b..07c333d4781 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -334,6 +334,10 @@ typedef struct clib_bitmap_t * workers; u32 hqos_enabled; dpdk_device_config_hqos_t hqos; + u8 tso; +#define DPDK_DEVICE_TSO_DEFAULT 0 +#define DPDK_DEVICE_TSO_OFF 1 +#define DPDK_DEVICE_TSO_ON 2 } dpdk_device_config_t; typedef struct diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 4b4bed4ee07..e5a796bdf9c 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -207,6 +207,7 @@ dpdk_lib_init (dpdk_main_t * dm) int i; clib_error_t *error; vlib_main_t *vm = vlib_get_main (); + vnet_main_t *vnm = vnet_get_main (); vlib_thread_main_t *tm = vlib_get_thread_main (); vnet_device_main_t *vdm = &vnet_device_main; vnet_sw_interface_t *sw; @@ -739,6 +740,23 @@ dpdk_lib_init (dpdk_main_t * dm) if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD && hi != NULL) hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD; + if (devconf->tso == DPDK_DEVICE_TSO_ON) + { + if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD && hi != NULL) + { + /*tcp_udp checksum must be enabled*/ + if (hi->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD) + { + hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO; + vnm->interface_main.gso_interface_count++; + xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO | + DEV_TX_OFFLOAD_UDP_TSO; + } + else + return clib_error_return (0, "TSO: TCP/UDP checksum offload must be enabled"); + } + } + dpdk_device_setup (xd); if (vec_len (xd->errors)) @@ -1024,6 +1042,7 @@ dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr, devconf->pci_addr.as_u32 = pci_addr.as_u32; devconf->hqos_enabled = 0; + devconf->tso = DPDK_DEVICE_TSO_DEFAULT; #if 0 dpdk_device_config_hqos_default (&devconf->hqos); #endif @@ -1072,6 +1091,14 @@ dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr, { devconf->hqos_enabled = 1; } + else if (unformat (input, "tso on")) + { + devconf->tso = DPDK_DEVICE_TSO_ON; + } + else if (unformat (input, "tso off")) + { + devconf->tso = DPDK_DEVICE_TSO_OFF; + } else { error = clib_error_return (0, "unknown input `%U'", @@ -1378,6 +1405,9 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) devconf->vlan_strip_offload = conf->default_devconf.vlan_strip_offload; + /* copy tso config from default device */ + _(tso) + /* add DPDK EAL whitelist/blacklist entry */ if (num_whitelisted > 0 && devconf->is_blacklisted == 0) { |