conf: Add support for virtio-net.rx_queue_size

https://bugzilla.redhat.com/show_bug.cgi?id=1366989

QEMU added another virtio-net tunable [1]. It basically allows
users to set the size of RX virtio ring. But because virtio-net
uses two separate ring buffers to pass data from/to guest they
named it explicitly rx_queue_size. We should expose it in our XML
too.

1: http://lists.nongnu.org/archive/html/qemu-devel/2016-08/msg02029.html

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2016-08-18 18:19:13 +02:00
parent 13350a17e4
commit c56cdf2593
10 changed files with 145 additions and 1 deletions

View File

@ -4674,7 +4674,7 @@ qemu-kvm -net nic,model=? /dev/null
&lt;source network='default'/&gt;
&lt;target dev='vnet1'/&gt;
&lt;model type='virtio'/&gt;
<b>&lt;driver name='vhost' txmode='iothread' ioeventfd='on' event_idx='off' queues='5'&gt;
<b>&lt;driver name='vhost' txmode='iothread' ioeventfd='on' event_idx='off' queues='5' rx_queue_size='256'&gt;
&lt;host csum='off' gso='off' tso4='off' tso6='off' ecn='off' ufo='off' mrg_rxbuf='off'/&gt;
&lt;guest csum='off' tso4='off' tso6='off' ecn='off' ufo='off'/&gt;
&lt;/driver&gt;
@ -4790,6 +4790,20 @@ qemu-kvm -net nic,model=? /dev/null
<span class="since">virtio-net since 1.0.6 (QEMU and KVM only)</span>
<span class="since">vhost-user since 1.2.17 (QEMU and KVM only)</span>
</dd>
<dt><code>rx_queue_size</code></dt>
<dd>
The optional <code>rx_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 2016-09-01) requires value to be a power of two
from [256, 1024] range.
<span class="since">Since 2.3.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>
</dl>
<p>
Offloading options for the host and guest can be configured using

View File

@ -2557,6 +2557,11 @@
<ref name="positiveInteger"/>
</attribute>
</optional>
<optional>
<attribute name='rx_queue_size'>
<ref name='positiveInteger'/>
</attribute>
</optional>
<optional>
<attribute name="txmode">
<choice>

View File

@ -8981,6 +8981,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
char *ioeventfd = NULL;
char *event_idx = NULL;
char *queues = NULL;
char *rx_queue_size = NULL;
char *str = NULL;
char *filter = NULL;
char *internal = NULL;
@ -9153,6 +9154,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
ioeventfd = virXMLPropString(cur, "ioeventfd");
event_idx = virXMLPropString(cur, "event_idx");
queues = virXMLPropString(cur, "queues");
rx_queue_size = virXMLPropString(cur, "rx_queue_size");
} else if (xmlStrEqual(cur->name, BAD_CAST "filterref")) {
if (filter) {
virReportError(VIR_ERR_XML_ERROR, "%s",
@ -9536,6 +9538,16 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
if (q > 1)
def->driver.virtio.queues = q;
}
if (rx_queue_size) {
unsigned int q;
if (virStrToLong_uip(rx_queue_size, NULL, 10, &q) < 0) {
virReportError(VIR_ERR_XML_DETAIL,
_("'rx_queue_size' attribute must be positive number: %s"),
rx_queue_size);
goto error;
}
def->driver.virtio.rx_queue_size = q;
}
if ((str = virXPathString("string(./driver/host/@csum)", ctxt))) {
if ((val = virTristateSwitchTypeFromString(str)) <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@ -9716,6 +9728,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
VIR_FREE(ioeventfd);
VIR_FREE(event_idx);
VIR_FREE(queues);
VIR_FREE(rx_queue_size);
VIR_FREE(str);
VIR_FREE(filter);
VIR_FREE(type);
@ -20919,6 +20932,9 @@ virDomainVirtioNetDriverFormat(char **outstr,
}
if (def->driver.virtio.queues)
virBufferAsprintf(&buf, "queues='%u' ", def->driver.virtio.queues);
if (def->driver.virtio.rx_queue_size)
virBufferAsprintf(&buf, "rx_queue_size='%u' ",
def->driver.virtio.rx_queue_size);
virBufferTrim(&buf, " ", -1);

View File

@ -906,6 +906,7 @@ struct _virDomainNetDef {
virTristateSwitch ioeventfd;
virTristateSwitch event_idx;
unsigned int queues; /* Multiqueue virtio-net */
unsigned int rx_queue_size;
struct {
virTristateSwitch csum;
virTristateSwitch gso;

View File

@ -2475,6 +2475,13 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
"not supported by QEMU"));
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;
}
}
ret = 0;

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<controller type='usb' index='0'/>
<interface type='user'>
<mac address='00:11:22:33:44:55'/>
<model type='virtio'/>
<driver rx_queue_size='511'/>
</interface>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<controller type='usb' index='0'/>
<interface type='user'>
<mac address='00:11:22:33:44:55'/>
<model type='virtio'/>
<driver rx_queue_size='512'/>
</interface>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -1047,6 +1047,7 @@ mymain(void)
QEMU_CAPS_VIRTIO_S390);
DO_TEST("net-virtio-ccw",
QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390);
DO_TEST_PARSE_ERROR("net-virtio-rxqueuesize-invalid-size", NONE);
DO_TEST("net-eth", NONE);
DO_TEST("net-eth-ifname", NONE);
DO_TEST("net-eth-names", NONE);

View File

@ -0,0 +1,41 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<interface type='user'>
<mac address='00:11:22:33:44:55'/>
<model type='virtio'/>
<driver rx_queue_size='512'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</memballoon>
</devices>
</domain>

View File

@ -514,6 +514,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-hostdev", NONE);
DO_TEST("net-hostdev-vfio", NONE);
DO_TEST("net-midonet", NONE);