https://bugzilla.redhat.com/show_bug.cgi?id=1460323
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 <mprivozn(a)redhat.com>
---
docs/formatdomain.html.in | 16 +++++++++++++++-
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, 67 insertions(+), 13 deletions(-)
rename tests/qemuxml2argvdata/{qemuxml2argv-net-virtio-rxqueuesize.args =>
qemuxml2argv-net-virtio-rxtxqueuesize.args} (85%)
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 7f4bc1d21..d37c89eff 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5065,7 +5065,7 @@ qemu-kvm -net nic,model=? /dev/null
<source network='default'/>
<target dev='vnet1'/>
<model type='virtio'/>
- <b><driver name='vhost' txmode='iothread'
ioeventfd='on' event_idx='off' queues='5'
rx_queue_size='256'>
+ <b><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>
@@ -5195,6 +5195,20 @@ qemu-kvm -net nic,model=? /dev/null
<b>In general you should leave this option alone, unless you
are very certain you know what you are doing.</b>
</dd>
+ <dt><code>tx_queue_size</code></dt>
+ <dd>
+ The optional <code>tx_queue_size</code> 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, latest
+ QEMU (as of 2017-07-13) requires value to be a power of two
+ from [256, 1024] range.
+ <span class="since">Since 3.6.0 (QEMU and KVM
only)</span><br/><br/>
+
+ <b>In general you should leave this option alone, unless you
+ are very certain you know what you are doing.</b>
+ </dd>
<dt>virtio options</dt>
<dd>
For virtio interfaces,
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 77136108a..7e133a8c1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2702,6 +2702,11 @@
<ref name='positiveInteger'/>
</attribute>
</optional>
+ <optional>
+ <attribute name='tx_queue_size'>
+ <ref name='positiveInteger'/>
+ </attribute>
+ </optional>
<optional>
<attribute name="txmode">
<choice>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 570cc5c93..7cf638da4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9863,6 +9863,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;
@@ -10036,6 +10037,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",
@@ -10433,6 +10435,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,
@@ -10630,6 +10642,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);
@@ -22497,6 +22510,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 1baf85453..1cb8b802c 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 db9f9b8b1..f502dd464 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -430,6 +430,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"virtio.iommu_platform",
"virtio.ats",
"loadparm",
+ "virtio-net.tx_queue_size",
);
@@ -1695,6 +1696,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 fb22815e9..63e792a19 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -416,6 +416,7 @@ typedef enum {
QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM, /* virtio-*-pci.iommu_platform */
QEMU_CAPS_VIRTIO_PCI_ATS, /* virtio-*-pci.ats */
QEMU_CAPS_LOADPARM, /* -machine loadparm */
+ 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 e290abff6..43fba3b0a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3790,6 +3790,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 ae260de00..b17727811 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3169,11 +3169,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 85%
rename from tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.args
rename to tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.args
index 07c358a02..c78da3d17 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.args
@@ -21,7 +21,7 @@ server,nowait \
-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 d64e31df2..b51931d52 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxqueuesize.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-rxtxqueuesize.xml
@@ -22,7 +22,7 @@
<interface type='user'>
<mac address='00:11:22:33:44:55'/>
<model type='virtio'/>
- <driver rx_queue_size='512'/>
+ <driver rx_queue_size='512' tx_queue_size='1024'/>
</interface>
<memballoon model='virtio'/>
</devices>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 302c9c892..8ad2ca71b 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1146,8 +1146,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 78433026c..5c33a58ad 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxqueuesize.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-virtio-rxtxqueuesize.xml
@@ -29,7 +29,7 @@
<interface type='user'>
<mac address='00:11:22:33:44:55'/>
<model type='virtio'/>
- <driver rx_queue_size='512'/>
+ <driver rx_queue_size='512' tx_queue_size='1024'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
</interface>
<input type='mouse' bus='ps2'/>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 79347671f..578b07a95 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.13.0