dpdk: add TSO support in dpdk plugin. 86/20686/3
authorChenmin Sun <chenmin.sun@intel.com>
Wed, 17 Jul 2019 14:29:44 +0000 (22:29 +0800)
committerDamjan Marion <dmarion@me.com>
Mon, 19 Aug 2019 09:41:08 +0000 (09:41 +0000)
Type: feature

You can enable tso in starup.conf like this:
dev 0000:86:00.0{
tso on
}

TSO is disabled by default.

Change-Id: Ifdbaf5322f768c384aa54e532d7bf45e810ca01c
Signed-off-by: Chenmin Sun <chenmin.sun@intel.com>
src/plugins/dpdk/device/device.c
src/plugins/dpdk/device/dpdk.h
src/plugins/dpdk/device/init.c

index 8778d71..cb0448f 100644 (file)
@@ -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
index 0ec4ec3..07c333d 100644 (file)
@@ -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
index 4b4bed4..e5a796b 100644 (file)
@@ -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)
       {