From d69aa50cc1da54200db61b797e782f2a158f2a2e Mon Sep 17 00:00:00 2001 Message-Id: From: "Michael S. Tsirkin" Date: Thu, 29 Mar 2012 14:09:47 +0200 Subject: [PATCH 1/2] macvtap: rhel6.2 compatibility RH-Author: Michael S. Tsirkin Message-id: <20120329140947.GB14070@redhat.com> Patchwork-id: 39028 O-Subject: [PATCHv2 RHEL6.3] macvtap: rhel6.2 compatibility Bugzilla: 806975 RH-Acked-by: Xiao Wang RH-Acked-by: Amos Kong RH-Acked-by: Amit Shah It turns out that because of https://bugzilla.redhat.com/show_bug.cgi?id=789362 rhel6.2 kernel macvtap does not support rx mergeable buffers when used with vhost-net. Since this is a guest visible feature we can not change it. Also, we don't currently know whether a device has macvtap backend. As a solution, add a rhel specific property that signals a macvtap backend. When that is detected + rhel6.2 mode + vhost-net, disable mergeable buffers. Note: by convention x-* marks internal features which should never be changed by management or users. Brew build: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=4225359 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=806975 Tested: developer testing Signed-off-by: Michael S. Tsirkin --- Reposting with 6.3 tag. Sorry about the noise. Changes from v1: - Typo fixes for typos reported by Jason on IRC - Add some more comments hw/pc.c | 12 +++++++++++- hw/virtio-net.c | 9 +++++++++ hw/virtio-net.h | 1 + hw/virtio-pci.c | 18 ++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletions(-) Signed-off-by: Michal Novotny --- hw/pc.c | 12 +++++++++++- hw/virtio-net.c | 9 +++++++++ hw/virtio-net.h | 1 + hw/virtio-pci.c | 18 ++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index d17acc5..60e289b 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1561,6 +1561,12 @@ static void rhel_common_init(const char *type1_version, strlen(buf) + 1, buf); } +#define PC_RHEL6_2_COMPAT \ + {\ + .driver = "virtio-net-pci",\ + .property = "x-__com_redhat_rhel620_compat",\ + .value = "on",\ + } #define PC_RHEL6_1_COMPAT \ {\ .driver = "usb-tablet",\ @@ -1590,7 +1596,7 @@ static void rhel_common_init(const char *type1_version, .driver = "virtio-balloon",\ .property = "event_idx",\ .value = "off",\ - } + }, PC_RHEL6_2_COMPAT #define PC_RHEL6_0_COMPAT \ {\ @@ -1638,6 +1644,10 @@ static QEMUMachine pc_machine_rhel620 = { .desc = "RHEL 6.2.0 PC", .init = pc_init_rhel620, .max_cpus = 255, + .compat_props = (GlobalProperty[]) { + PC_RHEL6_2_COMPAT, + { /* end of list */ } + }, }; static void pc_init_rhel610(ram_addr_t ram_size, diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 01d9467..0926cf6 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -54,6 +54,7 @@ typedef struct VirtIONet uint8_t nouni; uint8_t nobcast; uint8_t vhost_started; + bool macvtap_rhel620_compat; struct { int in_use; int first_multi; @@ -226,6 +227,13 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features) if (!tap_get_vhost_net(n->nic->nc.peer)) { return features; } + /* + * In rhel 6.1 and 6.2 macvtap does not support rx mergeable + * buffers when used with vhost-net. + */ + if (n->macvtap_rhel620_compat) { + features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF); + } return vhost_net_get_features(tap_get_vhost_net(n->nic->nc.peer), features); } @@ -992,6 +1000,7 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx_bh); n->tx_bh = qemu_bh_new(virtio_net_tx_bh, n); } + n->macvtap_rhel620_compat = net->macvtap_rhel620_compat; n->ctrl_vq = virtio_add_queue(&n->vdev, 64, virtio_net_handle_ctrl); qemu_macaddr_default_if_unset(&conf->macaddr); memcpy(&n->mac[0], &conf->macaddr, sizeof(n->mac)); diff --git a/hw/virtio-net.h b/hw/virtio-net.h index 5eacda6..fde3697 100644 --- a/hw/virtio-net.h +++ b/hw/virtio-net.h @@ -61,6 +61,7 @@ typedef struct virtio_net_conf uint32_t txtimer; int32_t txburst; char *tx; + bool macvtap_rhel620_compat; } virtio_net_conf; /* Maximum packet size we can receive from tap device: header + 64k */ diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index b2a558d..e8c08bf 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -89,6 +89,15 @@ #define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1 #define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT) +/* Enabled work-arounds for migration with macvtap backend */ +#define VIRTIO_PCI_FLAG_MACVTAP_BIT 2 +#define VIRTIO_PCI_FLAG_MACVTAP (1 << VIRTIO_PCI_FLAG_MACVTAP_BIT) + +/* Enabled compatibility for migration for rhel6.2.0 and older */ +#define VIRTIO_PCI_FLAG_RHEL620_BIT 3 +#define VIRTIO_PCI_FLAG_RHEL620 (1 << VIRTIO_PCI_FLAG_RHEL620_BIT) + + /* QEMU doesn't strictly need write barriers since everything runs in * lock-step. We'll leave the calls to wmb() in though to make it obvious for * KVM or if kqemu gets SMP support. @@ -884,6 +893,11 @@ static int virtio_net_init_pci(PCIDevice *pci_dev) VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIODevice *vdev; + /* Set rhel6.2 or older compatibility mode for macvtap. */ + proxy->net.macvtap_rhel620_compat = + (proxy->flags & VIRTIO_PCI_FLAG_RHEL620) && + (proxy->flags & VIRTIO_PCI_FLAG_MACVTAP); + vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net); vdev->nvectors = proxy->nvectors; @@ -989,6 +1003,10 @@ static PCIDeviceInfo virtio_info[] = { .qdev.props = (Property[]) { DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), + DEFINE_PROP_BIT("__com_redhat_macvtap_compat", VirtIOPCIProxy, + flags, VIRTIO_PCI_FLAG_MACVTAP_BIT, false), + DEFINE_PROP_BIT("x-__com_redhat_rhel620_compat", VirtIOPCIProxy, + flags, VIRTIO_PCI_FLAG_RHEL620_BIT, false), DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3), DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features), DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic), -- 1.7.7.6