virtio_net: Bypass backends for MTU feature negotiation

This patch adds a new internal "x-mtu-bypass-backend" property
to bypass backends for MTU feature negotiation.

When this property is set, the MTU feature is negotiated as soon
as supported by the guest and a MTU value is set via the host_mtu
parameter. In case the backend advertises the feature (e.g. DPDK's
vhost-user backend), the feature negotiation is propagated down to
the backend.

When this property is not set, the backend has to support the MTU
feature for its negotiation to succeed.

For compatibility purpose, this property is disabled for machine
types v2.9 and older.

Cc: Aaron Conole <aconole@redhat.com>
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Vlad Yasevich <vyasevic@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Maxime Coquelin 2017-05-23 14:31:19 +02:00 committed by Michael S. Tsirkin
parent c10595fb34
commit 75ebec11af
4 changed files with 22 additions and 1 deletions

View File

@ -589,7 +589,15 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
if (!get_vhost_net(nc->peer)) { if (!get_vhost_net(nc->peer)) {
return features; return features;
} }
return vhost_net_get_features(get_vhost_net(nc->peer), features); features = vhost_net_get_features(get_vhost_net(nc->peer), features);
vdev->backend_features = features;
if (n->mtu_bypass_backend &&
(n->host_features & 1ULL << VIRTIO_NET_F_MTU)) {
features |= (1ULL << VIRTIO_NET_F_MTU);
}
return features;
} }
static uint64_t virtio_net_bad_features(VirtIODevice *vdev) static uint64_t virtio_net_bad_features(VirtIODevice *vdev)
@ -640,6 +648,11 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features)
VirtIONet *n = VIRTIO_NET(vdev); VirtIONet *n = VIRTIO_NET(vdev);
int i; int i;
if (n->mtu_bypass_backend &&
!virtio_has_feature(vdev->backend_features, VIRTIO_NET_F_MTU)) {
features &= ~(1ULL << VIRTIO_NET_F_MTU);
}
virtio_net_set_multiqueue(n, virtio_net_set_multiqueue(n,
virtio_has_feature(features, VIRTIO_NET_F_MQ)); virtio_has_feature(features, VIRTIO_NET_F_MQ));
@ -2093,6 +2106,8 @@ static Property virtio_net_properties[] = {
DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size, DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size,
VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE), VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE),
DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0), DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
true),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };

View File

@ -10,6 +10,10 @@
.driver = "intel-iommu",\ .driver = "intel-iommu",\
.property = "pt",\ .property = "pt",\
.value = "off",\ .value = "off",\
},{\
.driver = "virtio-net-device",\
.property = "x-mtu-bypass-backend",\
.value = "off",\
}, },
#define HW_COMPAT_2_8 \ #define HW_COMPAT_2_8 \

View File

@ -97,6 +97,7 @@ typedef struct VirtIONet {
QEMUTimer *announce_timer; QEMUTimer *announce_timer;
int announce_counter; int announce_counter;
bool needs_vnet_hdr_swap; bool needs_vnet_hdr_swap;
bool mtu_bypass_backend;
} VirtIONet; } VirtIONet;
void virtio_net_set_netclient_name(VirtIONet *n, const char *name, void virtio_net_set_netclient_name(VirtIONet *n, const char *name,

View File

@ -79,6 +79,7 @@ struct VirtIODevice
uint16_t queue_sel; uint16_t queue_sel;
uint64_t guest_features; uint64_t guest_features;
uint64_t host_features; uint64_t host_features;
uint64_t backend_features;
size_t config_len; size_t config_len;
void *config; void *config;
uint16_t config_vector; uint16_t config_vector;