diff --git a/SOURCES/libvirt-Add-support-for-virtio-net.tx_queue_size.patch b/SOURCES/libvirt-Add-support-for-virtio-net.tx_queue_size.patch new file mode 100644 index 0000000..7e04950 --- /dev/null +++ b/SOURCES/libvirt-Add-support-for-virtio-net.tx_queue_size.patch @@ -0,0 +1,317 @@ +From 9b3184784e1243a81a4b8de350fb0434a1ad1f28 Mon Sep 17 00:00:00 2001 +Message-Id: <9b3184784e1243a81a4b8de350fb0434a1ad1f28@dist-git> +From: Michal Privoznik +Date: Fri, 18 Aug 2017 09:35:54 +0200 +Subject: [PATCH] Add support for virtio-net.tx_queue_size + +RHEL-7.5: https://bugzilla.redhat.com/show_bug.cgi?id=1462653 +RHEL-7.4.z: https://bugzilla.redhat.com/show_bug.cgi?id=1482514 + +Just like I've added support for setting rx_queue_size (in +c56cdf259 and friends), qemu just gained support for setting tx +ring size. + +Signed-off-by: Michal Privoznik +(cherry picked from commit 2074ef6cd4a2e033813ec091487d027a85f73509) +Signed-off-by: Michal Privoznik + +Conflicts: + src/qemu/qemu_capabilities.c: + src/qemu/qemu_capabilities.h: Context because of some caps + missing +Signed-off-by: Michal Privoznik +Signed-off-by: Jiri Denemark +--- + docs/formatdomain.html.in | 15 ++++++++++++++- + docs/schemas/domaincommon.rng | 5 +++++ + src/conf/domain_conf.c | 16 ++++++++++++++++ + src/conf/domain_conf.h | 1 + + src/qemu/qemu_capabilities.c | 2 ++ + src/qemu/qemu_capabilities.h | 1 + + src/qemu/qemu_command.c | 8 ++++++++ + src/qemu/qemu_domain.c | 16 +++++++++++----- + ...e.args => qemuxml2argv-net-virtio-rxtxqueuesize.args} | 4 ++-- + ...ize.xml => qemuxml2argv-net-virtio-rxtxqueuesize.xml} | 2 +- + tests/qemuxml2argvtest.c | 5 +++-- + ...e.xml => qemuxml2xmlout-net-virtio-rxtxqueuesize.xml} | 2 +- + tests/qemuxml2xmltest.c | 2 +- + 13 files changed, 66 insertions(+), 13 deletions(-) + rename tests/qemuxml2argvdata/{qemuxml2argv-net-virtio-rxqueuesize.args => qemuxml2argv-net-virtio-rxtxqueuesize.args} (83%) + rename tests/qemuxml2argvdata/{qemuxml2argv-net-virtio-rxqueuesize.xml => qemuxml2argv-net-virtio-rxtxqueuesize.xml} (93%) + rename tests/qemuxml2xmloutdata/{qemuxml2xmlout-net-virtio-rxqueuesize.xml => qemuxml2xmlout-net-virtio-rxtxqueuesize.xml} (96%) + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index dc8e7d2dc7..024debe862 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -5038,7 +5038,7 @@ qemu-kvm -net nic,model=? /dev/null + <source network='default'/> + <target dev='vnet1'/> + <model type='virtio'/> +- <driver name='vhost' txmode='iothread' ioeventfd='on' event_idx='off' queues='5' rx_queue_size='256'> ++ <driver name='vhost' txmode='iothread' ioeventfd='on' event_idx='off' queues='5' rx_queue_size='256' tx_queue_size='256'> + <host csum='off' gso='off' tso4='off' tso6='off' ecn='off' ufo='off' mrg_rxbuf='off'/> + <guest csum='off' tso4='off' tso6='off' ecn='off' ufo='off'/> + </driver> +@@ -5168,6 +5168,19 @@ qemu-kvm -net nic,model=? /dev/null + In general you should leave this option alone, unless you + are very certain you know what you are doing. + ++
tx_queue_size
++
++ The optional tx_queue_size attribute controls ++ the size of virtio ring for each queue as described above. ++ The default value is hypervisor dependent and may change ++ across its releases. Moreover, some hypervisors may pose ++ some restrictions on actual value. For instance, QEMU ++ v2.9 requires value to be a power of two from [256, 1024] range. ++ Since 3.7.0 (QEMU and KVM only)

++ ++ In general you should leave this option alone, unless you ++ are very certain you know what you are doing. ++
+
virtio options
+
+ For virtio interfaces, +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 78023ff4af..bb077ed5a0 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -2619,6 +2619,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index d8ca25da38..806582fb8f 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -9721,6 +9721,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + char *event_idx = NULL; + char *queues = NULL; + char *rx_queue_size = NULL; ++ char *tx_queue_size = NULL; + char *str = NULL; + char *filter = NULL; + char *internal = NULL; +@@ -9894,6 +9895,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + event_idx = virXMLPropString(cur, "event_idx"); + queues = virXMLPropString(cur, "queues"); + rx_queue_size = virXMLPropString(cur, "rx_queue_size"); ++ tx_queue_size = virXMLPropString(cur, "tx_queue_size"); + } else if (xmlStrEqual(cur->name, BAD_CAST "filterref")) { + if (filter) { + virReportError(VIR_ERR_XML_ERROR, "%s", +@@ -10291,6 +10293,16 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + } + def->driver.virtio.rx_queue_size = q; + } ++ if (tx_queue_size) { ++ unsigned int q; ++ if (virStrToLong_uip(tx_queue_size, NULL, 10, &q) < 0) { ++ virReportError(VIR_ERR_XML_DETAIL, ++ _("'tx_queue_size' attribute must be positive number: %s"), ++ tx_queue_size); ++ goto error; ++ } ++ def->driver.virtio.tx_queue_size = q; ++ } + if ((str = virXPathString("string(./driver/host/@csum)", ctxt))) { + if ((val = virTristateSwitchTypeFromString(str)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +@@ -10488,6 +10500,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + VIR_FREE(event_idx); + VIR_FREE(queues); + VIR_FREE(rx_queue_size); ++ VIR_FREE(tx_queue_size); + VIR_FREE(str); + VIR_FREE(filter); + VIR_FREE(type); +@@ -22264,6 +22277,9 @@ virDomainVirtioNetDriverFormat(char **outstr, + if (def->driver.virtio.rx_queue_size) + virBufferAsprintf(&buf, " rx_queue_size='%u'", + def->driver.virtio.rx_queue_size); ++ if (def->driver.virtio.tx_queue_size) ++ virBufferAsprintf(&buf, " tx_queue_size='%u'", ++ def->driver.virtio.tx_queue_size); + + virDomainVirtioOptionsFormat(&buf, def->virtio); + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 4c33b0d15e..7372a52856 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -967,6 +967,7 @@ struct _virDomainNetDef { + virTristateSwitch event_idx; + unsigned int queues; /* Multiqueue virtio-net */ + unsigned int rx_queue_size; ++ unsigned int tx_queue_size; + struct { + virTristateSwitch csum; + virTristateSwitch gso; +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index f22c11941c..6f8b1ac735 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -376,6 +376,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, + "intel-iommu.device-iotlb", /* 260 */ + "virtio.iommu_platform", + "virtio.ats", ++ "virtio-net.tx_queue_size", + ); + + +@@ -1642,6 +1643,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioNet[] = { + { "tx", QEMU_CAPS_VIRTIO_TX_ALG }, + { "event_idx", QEMU_CAPS_VIRTIO_NET_EVENT_IDX }, + { "rx_queue_size", QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE }, ++ { "tx_queue_size", QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE }, + { "host_mtu", QEMU_CAPS_VIRTIO_NET_HOST_MTU }, + }; + +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index c28c80d40a..281fe7d483 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -415,6 +415,7 @@ typedef enum { + QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB, /* intel-iommu.device-iotlb */ + QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM, /* virtio-*-pci.iommu_platform */ + QEMU_CAPS_VIRTIO_PCI_ATS, /* virtio-*-pci.ats */ ++ QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE, /* virtio-net-*.tx_queue_size */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index a4184b7378..f16029aa83 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3788,6 +3788,14 @@ qemuBuildNicDevStr(virDomainDefPtr def, + } + virBufferAsprintf(&buf, ",rx_queue_size=%u", net->driver.virtio.rx_queue_size); + } ++ if (usingVirtio && net->driver.virtio.tx_queue_size) { ++ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("virtio tx_queue_size option is not supported with this QEMU binary")); ++ goto error; ++ } ++ virBufferAsprintf(&buf, ",tx_queue_size=%u", net->driver.virtio.tx_queue_size); ++ } + + if (usingVirtio && net->mtu) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) { +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index c9c668b892..a41657099f 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -3121,11 +3121,17 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, + goto cleanup; + } + +- if (STREQ_NULLABLE(net->model, "virtio") && +- net->driver.virtio.rx_queue_size & (net->driver.virtio.rx_queue_size - 1)) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +- _("rx_queue_size has to be a power of two")); +- goto cleanup; ++ if (STREQ_NULLABLE(net->model, "virtio")) { ++ if (net->driver.virtio.rx_queue_size & (net->driver.virtio.rx_queue_size - 1)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("rx_queue_size has to be a power of two")); ++ goto cleanup; ++ } ++ if (net->driver.virtio.tx_queue_size & (net->driver.virtio.tx_queue_size - 1)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("tx_queue_size has to be a power of two")); ++ goto cleanup; ++ } + } + + if (net->mtu && +diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.args +similarity index 83% +rename from tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.args +rename to tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.args +index 7d275a723d..68b87b4ffe 100644 +--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.args ++++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.args +@@ -19,7 +19,7 @@ QEMU_AUDIO_DRV=none \ + -usb \ + -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ + -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +--device virtio-net-pci,rx_queue_size=512,vlan=0,id=net0,mac=00:11:22:33:44:55,\ +-bus=pci.0,addr=0x3 \ ++-device virtio-net-pci,rx_queue_size=512,tx_queue_size=1024,vlan=0,id=net0,\ ++mac=00:11:22:33:44:55,bus=pci.0,addr=0x3 \ + -net user,vlan=0,name=hostnet0 \ + -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 +diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.xml +similarity index 93% +rename from tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.xml +rename to tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.xml +index cfb4742fc6..14d357bba3 100644 +--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.xml ++++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.xml +@@ -22,7 +22,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 5ca27f105d..827fe90239 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1145,8 +1145,9 @@ mymain(void) + QEMU_CAPS_VIRTIO_S390); + DO_TEST("net-virtio-ccw", + QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390); +- DO_TEST("net-virtio-rxqueuesize", +- QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE); ++ DO_TEST("net-virtio-rxtxqueuesize", ++ QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE, ++ QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE); + DO_TEST_PARSE_ERROR("net-virtio-rxqueuesize-invalid-size", NONE); + DO_TEST("net-eth", NONE); + DO_TEST("net-eth-ifname", NONE); +diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxqueuesize.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxtxqueuesize.xml +similarity index 96% +rename from tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxqueuesize.xml +rename to tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxtxqueuesize.xml +index 5b41936063..34e1e40012 100644 +--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxqueuesize.xml ++++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxtxqueuesize.xml +@@ -29,7 +29,7 @@ + + + +- ++ +
+ + +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index f2abad00cf..62bce8d240 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -523,7 +523,7 @@ mymain(void) + DO_TEST("net-eth-ifname", NONE); + DO_TEST("net-eth-hostip", NONE); + DO_TEST("net-virtio-network-portgroup", NONE); +- DO_TEST("net-virtio-rxqueuesize", NONE); ++ DO_TEST("net-virtio-rxtxqueuesize", NONE); + DO_TEST("net-hostdev", NONE); + DO_TEST("net-hostdev-vfio", NONE); + DO_TEST("net-midonet", NONE); +-- +2.14.1 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index 6913178..0d1221d 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -228,7 +228,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 3.2.0 -Release: 14%{?dist}.2%{?extra_release} +Release: 14%{?dist}.3%{?extra_release} License: LGPLv2+ Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -481,6 +481,7 @@ Patch238: libvirt-qemu-Move-qemuProcessReconnect-to-the-end-of-qemu_process.c.pa Patch239: libvirt-qemu-Update-host-model-CPUs-on-reconnect.patch Patch240: libvirt-qemu-Fix-qemuDomainGetBlockInfo-allocation-value-setting.patch Patch241: libvirt-qemuDomainBuildNamespace-Handle-special-file-mount-points.patch +Patch242: libvirt-Add-support-for-virtio-net.tx_queue_size.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2329,6 +2330,9 @@ exit 0 %changelog +* Tue Aug 22 2017 Jiri Denemark - 3.2.0-14.el7_4.3 +- Add support for virtio-net.tx_queue_size (rhbz#1482514) + * Tue Jul 18 2017 Jiri Denemark - 3.2.0-14.el7_4.2 - qemu: Fix qemuDomainGetBlockInfo allocation value setting (rhbz#1470127) - qemuDomainBuildNamespace: Handle special file mount points (rhbz#1471660)