diff options
Diffstat (limited to 'src/vnet/devices/virtio')
-rw-r--r-- | src/vnet/devices/virtio/cli.c | 2 | ||||
-rw-r--r-- | src/vnet/devices/virtio/pci.c | 61 | ||||
-rw-r--r-- | src/vnet/devices/virtio/pci.h | 13 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio.api | 4 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio_api.c | 4 |
5 files changed, 77 insertions, 7 deletions
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); |