mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
Add support for virtio-net.tx_queue_size
https://bugzilla.redhat.com/show_bug.cgi?id=1462653
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@redhat.com>
This commit is contained in:
parent
8b9d017de3
commit
2074ef6cd4
@ -5074,7 +5074,7 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
<source network='default'/>
|
<source network='default'/>
|
||||||
<target dev='vnet1'/>
|
<target dev='vnet1'/>
|
||||||
<model type='virtio'/>
|
<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'/>
|
<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'/>
|
<guest csum='off' tso4='off' tso6='off' ecn='off' ufo='off'/>
|
||||||
</driver>
|
</driver>
|
||||||
@ -5204,6 +5204,19 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
<b>In general you should leave this option alone, unless you
|
<b>In general you should leave this option alone, unless you
|
||||||
are very certain you know what you are doing.</b>
|
are very certain you know what you are doing.</b>
|
||||||
</dd>
|
</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, QEMU
|
||||||
|
v2.9 requires value to be a power of two from [256, 1024] range.
|
||||||
|
<span class="since">Since 3.7.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>
|
<dt>virtio options</dt>
|
||||||
<dd>
|
<dd>
|
||||||
For virtio interfaces,
|
For virtio interfaces,
|
||||||
|
@ -2711,6 +2711,11 @@
|
|||||||
<ref name='positiveInteger'/>
|
<ref name='positiveInteger'/>
|
||||||
</attribute>
|
</attribute>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name='tx_queue_size'>
|
||||||
|
<ref name='positiveInteger'/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
<attribute name="txmode">
|
<attribute name="txmode">
|
||||||
<choice>
|
<choice>
|
||||||
|
@ -9833,6 +9833,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
char *event_idx = NULL;
|
char *event_idx = NULL;
|
||||||
char *queues = NULL;
|
char *queues = NULL;
|
||||||
char *rx_queue_size = NULL;
|
char *rx_queue_size = NULL;
|
||||||
|
char *tx_queue_size = NULL;
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
char *filter = NULL;
|
char *filter = NULL;
|
||||||
char *internal = NULL;
|
char *internal = NULL;
|
||||||
@ -10006,6 +10007,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
event_idx = virXMLPropString(cur, "event_idx");
|
event_idx = virXMLPropString(cur, "event_idx");
|
||||||
queues = virXMLPropString(cur, "queues");
|
queues = virXMLPropString(cur, "queues");
|
||||||
rx_queue_size = virXMLPropString(cur, "rx_queue_size");
|
rx_queue_size = virXMLPropString(cur, "rx_queue_size");
|
||||||
|
tx_queue_size = virXMLPropString(cur, "tx_queue_size");
|
||||||
} else if (xmlStrEqual(cur->name, BAD_CAST "filterref")) {
|
} else if (xmlStrEqual(cur->name, BAD_CAST "filterref")) {
|
||||||
if (filter) {
|
if (filter) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
@ -10403,6 +10405,16 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
}
|
}
|
||||||
def->driver.virtio.rx_queue_size = q;
|
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 ((str = virXPathString("string(./driver/host/@csum)", ctxt))) {
|
||||||
if ((val = virTristateSwitchTypeFromString(str)) <= 0) {
|
if ((val = virTristateSwitchTypeFromString(str)) <= 0) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
@ -10600,6 +10612,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
VIR_FREE(event_idx);
|
VIR_FREE(event_idx);
|
||||||
VIR_FREE(queues);
|
VIR_FREE(queues);
|
||||||
VIR_FREE(rx_queue_size);
|
VIR_FREE(rx_queue_size);
|
||||||
|
VIR_FREE(tx_queue_size);
|
||||||
VIR_FREE(str);
|
VIR_FREE(str);
|
||||||
VIR_FREE(filter);
|
VIR_FREE(filter);
|
||||||
VIR_FREE(type);
|
VIR_FREE(type);
|
||||||
@ -22497,6 +22510,9 @@ virDomainVirtioNetDriverFormat(char **outstr,
|
|||||||
if (def->driver.virtio.rx_queue_size)
|
if (def->driver.virtio.rx_queue_size)
|
||||||
virBufferAsprintf(&buf, " rx_queue_size='%u'",
|
virBufferAsprintf(&buf, " rx_queue_size='%u'",
|
||||||
def->driver.virtio.rx_queue_size);
|
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);
|
virDomainVirtioOptionsFormat(&buf, def->virtio);
|
||||||
|
|
||||||
|
@ -969,6 +969,7 @@ struct _virDomainNetDef {
|
|||||||
virTristateSwitch event_idx;
|
virTristateSwitch event_idx;
|
||||||
unsigned int queues; /* Multiqueue virtio-net */
|
unsigned int queues; /* Multiqueue virtio-net */
|
||||||
unsigned int rx_queue_size;
|
unsigned int rx_queue_size;
|
||||||
|
unsigned int tx_queue_size;
|
||||||
struct {
|
struct {
|
||||||
virTristateSwitch csum;
|
virTristateSwitch csum;
|
||||||
virTristateSwitch gso;
|
virTristateSwitch gso;
|
||||||
|
@ -435,7 +435,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
|
|||||||
|
|
||||||
/* 265 */
|
/* 265 */
|
||||||
"spapr-pci-host-bridge.numa_node",
|
"spapr-pci-host-bridge.numa_node",
|
||||||
"vnc-multi-servers"
|
"vnc-multi-servers",
|
||||||
|
"virtio-net.tx_queue_size",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -1705,6 +1706,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioNet[] = {
|
|||||||
{ "tx", QEMU_CAPS_VIRTIO_TX_ALG },
|
{ "tx", QEMU_CAPS_VIRTIO_TX_ALG },
|
||||||
{ "event_idx", QEMU_CAPS_VIRTIO_NET_EVENT_IDX },
|
{ "event_idx", QEMU_CAPS_VIRTIO_NET_EVENT_IDX },
|
||||||
{ "rx_queue_size", QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE },
|
{ "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 },
|
{ "host_mtu", QEMU_CAPS_VIRTIO_NET_HOST_MTU },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -422,6 +422,7 @@ typedef enum {
|
|||||||
/* 265 */
|
/* 265 */
|
||||||
QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* spapr-pci-host-bridge.numa_node= */
|
QEMU_CAPS_SPAPR_PCI_HOST_BRIDGE_NUMA_NODE, /* spapr-pci-host-bridge.numa_node= */
|
||||||
QEMU_CAPS_VNC_MULTI_SERVERS, /* -vnc vnc=unix:/path */
|
QEMU_CAPS_VNC_MULTI_SERVERS, /* -vnc vnc=unix:/path */
|
||||||
|
QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE, /* virtio-net-*.tx_queue_size */
|
||||||
|
|
||||||
QEMU_CAPS_LAST /* this must always be the last item */
|
QEMU_CAPS_LAST /* this must always be the last item */
|
||||||
} virQEMUCapsFlags;
|
} virQEMUCapsFlags;
|
||||||
|
@ -3725,6 +3725,14 @@ qemuBuildNicDevStr(virDomainDefPtr def,
|
|||||||
}
|
}
|
||||||
virBufferAsprintf(&buf, ",rx_queue_size=%u", net->driver.virtio.rx_queue_size);
|
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 (usingVirtio && net->mtu) {
|
||||||
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
|
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_HOST_MTU)) {
|
||||||
|
@ -3226,12 +3226,18 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STREQ_NULLABLE(net->model, "virtio") &&
|
if (STREQ_NULLABLE(net->model, "virtio")) {
|
||||||
net->driver.virtio.rx_queue_size & (net->driver.virtio.rx_queue_size - 1)) {
|
if (net->driver.virtio.rx_queue_size & (net->driver.virtio.rx_queue_size - 1)) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("rx_queue_size has to be a power of two"));
|
_("rx_queue_size has to be a power of two"));
|
||||||
goto cleanup;
|
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 &&
|
if (net->mtu &&
|
||||||
!qemuDomainNetSupportsMTU(net->type)) {
|
!qemuDomainNetSupportsMTU(net->type)) {
|
||||||
|
@ -21,7 +21,7 @@ server,nowait \
|
|||||||
-usb \
|
-usb \
|
||||||
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
|
-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 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,\
|
-device virtio-net-pci,rx_queue_size=512,tx_queue_size=1024,vlan=0,id=net0,\
|
||||||
bus=pci.0,addr=0x3 \
|
mac=00:11:22:33:44:55,bus=pci.0,addr=0x3 \
|
||||||
-net user,vlan=0,name=hostnet0 \
|
-net user,vlan=0,name=hostnet0 \
|
||||||
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
|
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
|
@ -22,7 +22,7 @@
|
|||||||
<interface type='user'>
|
<interface type='user'>
|
||||||
<mac address='00:11:22:33:44:55'/>
|
<mac address='00:11:22:33:44:55'/>
|
||||||
<model type='virtio'/>
|
<model type='virtio'/>
|
||||||
<driver rx_queue_size='512'/>
|
<driver rx_queue_size='512' tx_queue_size='1024'/>
|
||||||
</interface>
|
</interface>
|
||||||
<memballoon model='virtio'/>
|
<memballoon model='virtio'/>
|
||||||
</devices>
|
</devices>
|
@ -1167,8 +1167,9 @@ mymain(void)
|
|||||||
QEMU_CAPS_VIRTIO_S390);
|
QEMU_CAPS_VIRTIO_S390);
|
||||||
DO_TEST("net-virtio-ccw",
|
DO_TEST("net-virtio-ccw",
|
||||||
QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390);
|
QEMU_CAPS_VIRTIO_CCW, QEMU_CAPS_VIRTIO_S390);
|
||||||
DO_TEST("net-virtio-rxqueuesize",
|
DO_TEST("net-virtio-rxtxqueuesize",
|
||||||
QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE);
|
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_PARSE_ERROR("net-virtio-rxqueuesize-invalid-size", NONE);
|
||||||
DO_TEST("net-eth", NONE);
|
DO_TEST("net-eth", NONE);
|
||||||
DO_TEST("net-eth-ifname", NONE);
|
DO_TEST("net-eth-ifname", NONE);
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<interface type='user'>
|
<interface type='user'>
|
||||||
<mac address='00:11:22:33:44:55'/>
|
<mac address='00:11:22:33:44:55'/>
|
||||||
<model type='virtio'/>
|
<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'/>
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
|
||||||
</interface>
|
</interface>
|
||||||
<input type='mouse' bus='ps2'/>
|
<input type='mouse' bus='ps2'/>
|
@ -537,7 +537,7 @@ mymain(void)
|
|||||||
DO_TEST("net-eth-ifname", NONE);
|
DO_TEST("net-eth-ifname", NONE);
|
||||||
DO_TEST("net-eth-hostip", NONE);
|
DO_TEST("net-eth-hostip", NONE);
|
||||||
DO_TEST("net-virtio-network-portgroup", 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", NONE);
|
||||||
DO_TEST("net-hostdev-vfio", NONE);
|
DO_TEST("net-hostdev-vfio", NONE);
|
||||||
DO_TEST("net-midonet", NONE);
|
DO_TEST("net-midonet", NONE);
|
||||||
|
Loading…
Reference in New Issue
Block a user