aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2019-05-02 13:54:59 +0200
committerDamjan Marion <dmarion@me.com>2019-05-27 11:40:38 +0000
commitbbd6b746e09cc4ae4239173081d95349e0263759 (patch)
treeb49f623111f0bb5680a25ee1560c2a9c6a1b73d5 /src
parent423fbb1deaed9db9eb662d4b7407fb7274cb8e90 (diff)
virtio: Add gso support for native virtio driver
Change-Id: I7b735f5a540e8c278bac88245acb3f8c041c49c0 Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Diffstat (limited to 'src')
-rw-r--r--src/vat/api_format.c30
-rw-r--r--src/vnet/devices/virtio/cli.c2
-rw-r--r--src/vnet/devices/virtio/pci.c61
-rw-r--r--src/vnet/devices/virtio/pci.h13
-rw-r--r--src/vnet/devices/virtio/virtio.api4
-rw-r--r--src/vnet/devices/virtio/virtio_api.c4
-rw-r--r--src/vpp/api/custom_dump.c2
7 files changed, 83 insertions, 33 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index b330a389ef8..c57f045fdd4 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -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, "") \
diff --git a/src/vnet/devices/virtio/cli.c b/src/vnet/devices/virtio/cli.c
index 956284c9716..10b545edb5e 100644
--- a/src/vnet/devices/virtio/cli.c
+++ b/src/vnet/devices/virtio/cli.c
@@ -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);
diff --git a/src/vnet/devices/virtio/pci.c b/src/vnet/devices/virtio/pci.c
index 3736225b25c..f53552a8436 100644
--- a/src/vnet/devices/virtio/pci.c
+++ b/src/vnet/devices/virtio/pci.c
@@ -557,6 +557,27 @@ virtio_pci_send_ctrl_msg (vlib_main_t * vm, virtio_if_t * vif,
}
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);
diff --git a/src/vnet/devices/virtio/pci.h b/src/vnet/devices/virtio/pci.h
index dcf9b146463..b1e29162108 100644
--- a/src/vnet/devices/virtio/pci.h
+++ b/src/vnet/devices/virtio/pci.h
@@ -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;
diff --git a/src/vnet/devices/virtio/virtio.api b/src/vnet/devices/virtio/virtio.api
index 3a40fa9a952..9e81b35c175 100644
--- a/src/vnet/devices/virtio/virtio.api
+++ b/src/vnet/devices/virtio/virtio.api
@@ -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;
};
diff --git a/src/vnet/devices/virtio/virtio_api.c b/src/vnet/devices/virtio/virtio_api.c
index 82ff791a866..d73e6f877d5 100644
--- a/src/vnet/devices/virtio/virtio_api.c
+++ b/src/vnet/devices/virtio/virtio_api.c
@@ -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);
diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c
index 0122496a6f6..e9175d6ddcd 100644
--- a/src/vpp/api/custom_dump.c
+++ b/src/vpp/api/custom_dump.c
@@ -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;
}