diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b1e38f00e42370e4daed12863eede72a493be028..5469fc37268e355930c585634a5b595b355989b6 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -5405,6 +5405,33 @@ qemu-kvm -net nic,model=? /dev/null Since 3.1.0
++... +<devices> + <interface type='network'> + <source network='default'/> + <target dev='vnet0'/> + <coalesce> + <rx> + <frames max='7'/> + </rx> + </coalesce> + </interface> +</devices> +...+ +
+ This element provides means of setting coalesce settings for
+ some interface devices (currently only type network
+ and bridge
. Currently there is just one attribute,
+ max
, to tweak, in element frames
for
+ the
rx
group, which accepts a non-negative integer
+ that specifies the maximum number of packets that will be
+ received before an interrupt.
+ Since 3.3.0
+
... diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index edc225fe50c5295740722a9e4f51429bc7f1c179..eb4b0f7437babbc7f06c80f93effb57218c2e7d1 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2508,6 +2508,9 @@+ + + @@ -5743,4 +5746,132 @@ + ++ + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 705deb39a1bfff28b91e8185c2b7f7dec5c42f06..cbeebdc568803ecf084c414efd1e82715b291ce1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6772,6 +6772,77 @@ virDomainNetIPInfoParseXML(const char *source, return ret; } + +static virNetDevCoalescePtr +virDomainNetDefCoalesceParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + virNetDevCoalescePtr ret = NULL; + xmlNodePtr save = NULL; + char *str = NULL; + unsigned long long tmp = 0; + + save = ctxt->node; + ctxt->node = node; + + str = virXPathString("string(./rx/frames/@max)", ctxt); + if (!str) + goto cleanup; + + if (!ret && VIR_ALLOC(ret) < 0) + goto cleanup; + + if (virStrToLong_ullp(str, NULL, 10, &tmp) < 0) { + virReportError(VIR_ERR_XML_DETAIL, + _("cannot parse value '%s' for coalesce parameter"), + str); + VIR_FREE(str); + goto error; + } + VIR_FREE(str); + + if (tmp > UINT32_MAX) { + virReportError(VIR_ERR_OVERFLOW, + _("value '%llu' is too big for coalesce " + "parameter, maximum is '%lu'"), + tmp, (unsigned long) UINT32_MAX); + goto error; + } + ret->rx_max_coalesced_frames = tmp; + + cleanup: + ctxt->node = save; + return ret; + + error: + VIR_FREE(ret); + goto cleanup; +} + +static void +virDomainNetDefCoalesceFormatXML(virBufferPtr buf, + virNetDevCoalescePtr coalesce) +{ + if (!coalesce || !coalesce->rx_max_coalesced_frames) + return; + + virBufferAddLit(buf, "+ ++ ++ + ++ ++ + ++ ++ + ++ + +\n"); + virBufferAdjustIndent(buf, 2); + + virBufferAddLit(buf, " \n"); +} + + static int virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED, xmlXPathContextPtr ctxt, @@ -10255,6 +10326,13 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, goto error; } + node = virXPathNode("./coalesce", ctxt); + if (node) { + def->coalesce = virDomainNetDefCoalesceParseXML(node, ctxt); + if (!def->coalesce) + goto error; + } + cleanup: ctxt->node = oldnode; VIR_FREE(macaddr); @@ -22147,6 +22225,8 @@ virDomainNetDefFormat(virBufferPtr buf, if (def->mtu) virBufferAsprintf(buf, "\n"); + virBufferAdjustIndent(buf, 2); + + virBufferAsprintf(buf, " \n"); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n", + coalesce->rx_max_coalesced_frames); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, " \n", def->mtu); + virDomainNetDefCoalesceFormatXML(buf, def->coalesce); + if (virDomainDeviceInfoFormat(buf, &def->info, flags | VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT | VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM) < 0) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7da554f8ee28eca0eed88ba4c91209d5041d93f4..3b6b1745161843ab2102e459feab6f142c232395 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -41,6 +41,7 @@ # include "numa_conf.h" # include "virnetdevmacvlan.h" # include "virsysinfo.h" +# include "virnetdev.h" # include "virnetdevip.h" # include "virnetdevvportprofile.h" # include "virnetdevbandwidth.h" @@ -1036,6 +1037,7 @@ struct _virDomainNetDef { int trustGuestRxFilters; /* enum virTristateBool */ int linkstate; unsigned int mtu; + virNetDevCoalescePtr coalesce; }; /* Used for prefix of ifname of any network name generated dynamically diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b3e1573c690d95b1e144c222c5504626a63b7aeb..d906fe6fdd4f7ca74f5261b46af14a10fedd4421 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2984,6 +2984,30 @@ qemuDomainDefValidate(const virDomainDef *def, } +static bool +qemuDomainNetSupportsCoalesce(virDomainNetType type) +{ + switch (type) { + case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_BRIDGE: + return true; + case VIR_DOMAIN_NET_TYPE_VHOSTUSER: + case VIR_DOMAIN_NET_TYPE_ETHERNET: + case VIR_DOMAIN_NET_TYPE_DIRECT: + case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_USER: + case VIR_DOMAIN_NET_TYPE_SERVER: + case VIR_DOMAIN_NET_TYPE_CLIENT: + case VIR_DOMAIN_NET_TYPE_MCAST: + case VIR_DOMAIN_NET_TYPE_INTERNAL: + case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_LAST: + break; + } + return false; +} + + static int qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, const virDomainDef *def ATTRIBUTE_UNUSED, @@ -3018,6 +3042,13 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, virDomainNetTypeToString(net->type)); goto cleanup; } + + if (net->coalesce && !qemuDomainNetSupportsCoalesce(net->type)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("coalesce settings on interface type %s are not supported"), + virDomainNetTypeToString(net->type)); + goto cleanup; + } } ret = 0; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-coalesce.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-coalesce.xml new file mode 100644 index 0000000000000000000000000000000000000000..b510324427d3272522b3fa3a29a59146d9dbe2e5 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-coalesce.xml @@ -0,0 +1,68 @@ + + diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-coalesce.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-coalesce.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd5fdbece52817f31b9beb9025cfc094f487446a --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-coalesce.xml @@ -0,0 +1,71 @@ +test +15d091de-0181-456b-9554-e4382dc1f1ab +1048576 +1048576 +1 ++ +hvm ++ + + + destroy +restart +restart ++ +/usr/bin/qemu-system-x86_64 ++ ++ + + + + ++ + + + + + + + ++ + + + ++ + + ++ ++ + + ++ + + ++ ++ + ++ + + + ++ + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index e4b510fd31ee5b10a1fe65ce62b5d1d10ff40076..2dccde746ef186e1ff2d7be1787ebc5939e4bb7c 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -528,6 +528,7 @@ mymain(void) DO_TEST("net-bandwidth", NONE); DO_TEST("net-bandwidth2", NONE); DO_TEST("net-mtu", NONE); + DO_TEST("net-coalesce", NONE); DO_TEST("serial-vc", NONE); DO_TEST("serial-pty", NONE);test +15d091de-0181-456b-9554-e4382dc1f1ab +1048576 +1048576 +1 ++ +hvm ++ + + + destroy +restart +restart ++ +/usr/bin/qemu-system-x86_64 ++ ++ + + + + ++ + + + + + + ++ + ++ + ++ + ++ + + + + ++ ++ + ++ + + + + ++ + + + ++ + + +