virtio: Add gso support for native virtio driver 91/19291/7
authorMohsin Kazmi <sykazmi@cisco.com>
Thu, 2 May 2019 11:54:59 +0000 (13:54 +0200)
committerDamjan Marion <dmarion@me.com>
Mon, 27 May 2019 11:40:38 +0000 (11:40 +0000)
Change-Id: I7b735f5a540e8c278bac88245acb3f8c041c49c0
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
src/vat/api_format.c
src/vnet/devices/virtio/cli.c
src/vnet/devices/virtio/pci.c
src/vnet/devices/virtio/pci.h
src/vnet/devices/virtio/virtio.api
src/vnet/devices/virtio/virtio_api.c
src/vpp/api/custom_dump.c

index b330a38..c57f045 100644 (file)
@@ -7681,9 +7681,9 @@ api_virtio_pci_create (vat_main_t * vam)
   vl_api_virtio_pci_create_t *mp;
   u8 mac_address[6];
   u8 random_mac = 1;
+  u8 gso_enabled = 0;
   u32 pci_addr = 0;
   u64 features = (u64) ~ (0ULL);
-  u32 rx_ring_sz = 0, tx_ring_sz = 0;
   int ret;
 
   clib_memset (mac_address, 0, sizeof (mac_address));
@@ -7699,10 +7699,8 @@ api_virtio_pci_create (vat_main_t * vam)
        ;
       else if (unformat (i, "features 0x%llx", &features))
        ;
-      else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
-       ;
-      else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
-       ;
+      else if (unformat (i, "gso-enabled"))
+       gso_enabled = 1;
       else
        break;
     }
@@ -7712,26 +7710,6 @@ api_virtio_pci_create (vat_main_t * vam)
       errmsg ("pci address must be non zero. ");
       return -99;
     }
-  if (!is_pow2 (rx_ring_sz))
-    {
-      errmsg ("rx ring size must be power of 2. ");
-      return -99;
-    }
-  if (rx_ring_sz > 32768)
-    {
-      errmsg ("rx ring size must be 32768 or lower. ");
-      return -99;
-    }
-  if (!is_pow2 (tx_ring_sz))
-    {
-      errmsg ("tx ring size must be power of 2. ");
-      return -99;
-    }
-  if (tx_ring_sz > 32768)
-    {
-      errmsg ("tx ring size must be 32768 or lower. ");
-      return -99;
-    }
 
   /* Construct the API message */
   M (VIRTIO_PCI_CREATE, mp);
@@ -22293,7 +22271,7 @@ _(tap_delete_v2,                                                        \
   "<vpp-if-name> | sw_if_index <id>")                                   \
 _(sw_interface_tap_v2_dump, "")                                         \
 _(virtio_pci_create,                                                    \
-  "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [tx-ring-size <num> [rx-ring-size <num>] [features <hex-value>]") \
+  "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
 _(virtio_pci_delete,                                                    \
   "<vpp-if-name> | sw_if_index <id>")                                   \
 _(sw_interface_virtio_pci_dump, "")                                     \
index 956284c..10b545e 100644 (file)
@@ -42,6 +42,8 @@ virtio_pci_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
        ;
       else if (unformat (line_input, "feature-mask 0x%llx", &feature_mask))
        args.features = feature_mask;
+      else if (unformat (line_input, "gso-enabled"))
+       args.gso_enabled = 1;
       else
        return clib_error_return (0, "unknown input `%U'",
                                  format_unformat_error, input);
index 3736225..f53552a 100644 (file)
@@ -556,6 +556,27 @@ virtio_pci_send_ctrl_msg (vlib_main_t * vm, virtio_if_t * vif,
   return status;
 }
 
+static int
+virtio_pci_enable_gso (vlib_main_t * vm, virtio_if_t * vif)
+{
+  virtio_main_t *vim = &virtio_main;
+  struct virtio_ctrl_msg gso_hdr;
+  virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
+
+  gso_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
+  gso_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
+  gso_hdr.status = VIRTIO_NET_ERR;
+  u64 offloads = VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO);
+  clib_memcpy (gso_hdr.data, &offloads, sizeof (offloads));
+
+  status = virtio_pci_send_ctrl_msg (vm, vif, &gso_hdr, sizeof (offloads));
+  virtio_log_debug (vim, vif, "enable gso");
+  return status;
+}
+
 static int
 virtio_pci_enable_multiqueue (vlib_main_t * vm, virtio_if_t * vif,
                              u16 num_queues)
@@ -720,8 +741,18 @@ virtio_negotiate_features (vlib_main_t * vm, virtio_if_t * vif,
    * if features are not requested
    * default: all supported features
    */
-  u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_MTU)
+  u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_CSUM)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_MTU)
     | VIRTIO_FEATURE (VIRTIO_NET_F_MAC)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GSO)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO4)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO6)
+    | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_UFO)
     | VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)
     | VIRTIO_FEATURE (VIRTIO_NET_F_STATUS)
     | VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)
@@ -1175,14 +1206,31 @@ virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
   else
     vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
 
-  if ((vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) &&
-      (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ)))
+  if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
     {
-      if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
-       virtio_log_warning (vim, vif, "multiqueue is not set");
+      if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) &&
+         args->gso_enabled)
+       {
+         if (virtio_pci_enable_gso (vm, vif))
+           {
+             virtio_log_warning (vim, vif, "gso is not enabled");
+           }
+         else
+           {
+             vif->gso_enabled = 1;
+             hw->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO;
+             vnm->interface_main.gso_interface_count++;
+           }
+       }
+      if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ))
+       {
+         if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
+           virtio_log_warning (vim, vif, "multiqueue is not set");
+       }
     }
   return;
 
+
 error:
   virtio_pci_delete_if (vm, vif);
   args->rv = VNET_API_ERROR_INVALID_INTERFACE;
@@ -1212,6 +1260,9 @@ virtio_pci_delete_if (vlib_main_t * vm, virtio_if_t * vif)
 
   virtio_pci_legacy_reset (vm, vif);
 
+  if (vif->gso_enabled)
+    vnm->interface_main.gso_interface_count--;
+
   if (vif->hw_if_index)
     {
       vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
index dcf9b14..b1e2916 100644 (file)
@@ -101,10 +101,22 @@ typedef enum
  * at the end of the used ring. Guest should ignore the used->flags field. */ \
   _ (VHOST_USER_F_PROTOCOL_FEATURES, 30)
 
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2
 #define VIRTIO_NET_F_MTU 3
 #define VIRTIO_NET_S_LINK_UP    1      /* Link is up */
 #define VIRTIO_NET_S_ANNOUNCE   2      /* Announcement is needed */
 
+/*
+ * Control network offloads
+ * Reconfigures the network offloads that Guest can handle.
+ * Available with the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ * Command data format matches the feature bit mask exactly.
+ * See VIRTIO_NET_F_GUEST_* for the list of offloads
+ * that can be enabled/disabled.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
+
 /* Common configuration */
 #define VIRTIO_PCI_CAP_COMMON_CFG       1
 /* Notifications */
@@ -233,6 +245,7 @@ typedef struct
   u8 mac_addr_set;
   u8 mac_addr[6];
   u64 features;
+  u8 gso_enabled;
   clib_error_t *error;
 } virtio_pci_create_if_args_t;
 
index 3a40fa9..9e81b35 100644 (file)
@@ -22,8 +22,7 @@ option version = "1.0.0";
                       0-15 domain, 16-23 bus, 24-28 slot, 29-31 function
     @param use_random_mac - let the system generate a unique mac address
     @param mac_address - mac addr to assign to the interface if use_radom not set
-    @param tx_ring_sz - the number of entries of TX ring
-    @param rx_ring_sz - the number of entries of RX ring
+    @param gso_enabled - enable gso feature if available, 1 to enable
     @param features - the virtio features which driver should negotiate with device
 */
 define virtio_pci_create
@@ -33,6 +32,7 @@ define virtio_pci_create
   u32 pci_addr;
   u8 use_random_mac;
   u8 mac_address[6];
+  u8 gso_enabled;
   u64 features;
 };
 
index 82ff791..d73e6f8 100644 (file)
@@ -66,6 +66,10 @@ vl_api_virtio_pci_create_t_handler (vl_api_virtio_pci_create_t * mp)
       ap->mac_addr_set = 1;
     }
   ap->sw_if_index = (u32) ~ 0;
+  if (mp->gso_enabled)
+    ap->gso_enabled = 1;
+  else
+    ap->gso_enabled = 0;
   ap->features = clib_net_to_host_u64 (mp->features);
 
   virtio_pci_create_if (vm, ap);
index 0122496..e9175d6 100644 (file)
@@ -613,6 +613,8 @@ static void *vl_api_virtio_pci_create_t_print
                format_ethernet_address, mp->mac_address);
   if (mp->features)
     s = format (s, "features 0x%llx ", clib_net_to_host_u64 (mp->features));
+  if (mp->gso_enabled)
+    s = format (s, "gso-enabled");
   FINISH;
 }