From 627adfaf4c1b732a1d5694a0510ecda7f6eef998 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Thu, 1 Jun 2017 09:24:15 +0200 Subject: [PATCH 07/13] virtio_net: Bypass backends for MTU feature negotiation RH-Author: Maxime Coquelin Message-id: <20170601092415.2215-1-maxime.coquelin@redhat.com> Patchwork-id: 75454 O-Subject: [RHEL7.4 qemu-kvm-rhev] virtio_net: Bypass backends for MTU feature negotiation Bugzilla: 1452756 RH-Acked-by: Laurent Vivier RH-Acked-by: Jens Freimann RH-Acked-by: Vlad Yasevich RH-Acked-by: Michael S. Tsirkin 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 RHEL7.3 (vs. v2.9 for upstream) and older. Cc: Aaron Conole Suggested-by: Michael S. Tsirkin Signed-off-by: Maxime Coquelin Reviewed-by: Vlad Yasevich Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin (cherry picked from commit 75ebec11afe49539f71cc1c494e3010f91c86adb) Signed-off-by: Miroslav Rezanina --- hw/net/virtio-net.c | 17 ++++++++++++++++- include/hw/compat.h | 4 ++++ include/hw/virtio/virtio-net.h | 1 + include/hw/virtio/virtio.h | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 7d091c9..39c336e 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -589,7 +589,15 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features, if (!get_vhost_net(nc->peer)) { 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) @@ -640,6 +648,11 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features) VirtIONet *n = VIRTIO_NET(vdev); 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_has_feature(features, VIRTIO_NET_F_MQ)); @@ -2090,6 +2103,8 @@ static Property virtio_net_properties[] = { DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE), 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(), }; diff --git a/include/hw/compat.h b/include/hw/compat.h index 8366acc..843958b 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -360,6 +360,10 @@ .driver = "e1000e",\ .property = "__redhat_e1000e_7_3_intr_state",\ .value = "on",\ + },{ /* HW_COMPAT_RHEL7_3 */ \ + .driver = "virtio-net-device",\ + .property = "x-mtu-bypass-backend",\ + .value = "off",\ }, #endif /* HW_COMPAT_H */ diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 1eec9a2..602b486 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -97,6 +97,7 @@ typedef struct VirtIONet { QEMUTimer *announce_timer; int announce_counter; bool needs_vnet_hdr_swap; + bool mtu_bypass_backend; } VirtIONet; void virtio_net_set_netclient_name(VirtIONet *n, const char *name, diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 7dcb53a..5faa359 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -79,6 +79,7 @@ struct VirtIODevice uint16_t queue_sel; uint64_t guest_features; uint64_t host_features; + uint64_t backend_features; size_t config_len; void *config; uint16_t config_vector; -- 1.8.3.1