From: Peter Krempa Date: Thu, 23 Feb 2023 12:48:35 +0000 (+0100) Subject: conf: Store the iothread 'poll' settings in the XML X-Git-Tag: v9.4.0-rc1~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83eee66f811cc81c632738b84129f006035a88d0;p=thirdparty%2Flibvirt.git conf: Store the iothread 'poll' settings in the XML Currently we allow configuring the 'poll-max-ns', 'poll-grow', and 'poll-shrink' parameters of qemu iothreads only during runtime and they are not persisted. Add XML machinery to persist them. Signed-off-by: Peter Krempa Reviewed-by: Ján Tomko --- diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 3b9251547e..99e0a4241c 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -740,7 +740,9 @@ host/guest with many LUNs. :since:`Since 1.2.8 (QEMU only)` - + + + ... @@ -766,6 +768,13 @@ host/guest with many LUNs. :since:`Since 1.2.8 (QEMU only)` ``thread_pool_max`` which allow setting lower and upper boundary for number of worker threads for given IOThread. While the former can be value of zero, the latter can't. :since:`Since 8.5.0` + :since:`Since 9.4.0` an optional sub-element ``poll`` with can be used to + override the hypervisor-default interval of polling for the iothread before + it switches back to events. The optional attribute ``max`` sets the maximum + time polling should be used in nanoseconds. Setting ``max`` to ``0`` disables + polling. Attributes ``grow`` and ``shrink`` override (or disable when set to + ``0`` the default steps for increasing/decreasing the polling interval if + the set interval is deemed insufficient or extensive. ``defaultiothread`` This element represents the default event loop within hypervisor, where I/O requests from devices not assigned to a specific IOThread are processed. diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 222dd989f5..ac7165bad4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -15721,6 +15721,7 @@ static virDomainIOThreadIDDef * virDomainIOThreadIDDefParseXML(xmlNodePtr node) { g_autoptr(virDomainIOThreadIDDef) iothrid = virDomainIOThreadIDDefNew(); + xmlNodePtr pollNode; if (virXMLPropUInt(node, "id", 10, VIR_XML_PROP_REQUIRED | VIR_XML_PROP_NONZERO, @@ -15737,6 +15738,28 @@ virDomainIOThreadIDDefParseXML(xmlNodePtr node) &iothrid->thread_pool_max, -1) < 0) return NULL; + if ((pollNode = virXMLNodeGetSubelement(node, "poll"))) { + int rc; + + if ((rc = virXMLPropULongLong(pollNode, "max", 10, VIR_XML_PROP_NONE, + &iothrid->poll_max_ns)) < 0) + return NULL; + + iothrid->set_poll_max_ns = rc == 1; + + if ((rc = virXMLPropULongLong(pollNode, "grow", 10, VIR_XML_PROP_NONE, + &iothrid->poll_grow)) < 0) + return NULL; + + iothrid->set_poll_grow = rc == 1; + + if ((rc = virXMLPropULongLong(pollNode, "shrink", 10, VIR_XML_PROP_NONE, + &iothrid->poll_shrink)) < 0) + return NULL; + + iothrid->set_poll_shrink = rc == 1; + } + return g_steal_pointer(&iothrid); } @@ -26630,6 +26653,9 @@ virDomainDefIothreadShouldFormat(const virDomainDef *def) for (i = 0; i < def->niothreadids; i++) { if (!def->iothreadids[i]->autofill || + def->iothreadids[i]->set_poll_max_ns || + def->iothreadids[i]->set_poll_grow || + def->iothreadids[i]->set_poll_shrink || def->iothreadids[i]->thread_pool_min >= 0 || def->iothreadids[i]->thread_pool_max >= 0) return true; @@ -26678,6 +26704,8 @@ virDomainDefIOThreadsFormat(virBuffer *buf, for (i = 0; i < def->niothreadids; i++) { virDomainIOThreadIDDef *iothread = def->iothreadids[i]; g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) iothreadChildBuf = VIR_BUFFER_INIT_CHILD(&childrenBuf); + g_auto(virBuffer) pollAttrBuf = VIR_BUFFER_INITIALIZER; virBufferAsprintf(&attrBuf, " id='%u'", iothread->iothread_id); @@ -26692,7 +26720,18 @@ virDomainDefIOThreadsFormat(virBuffer *buf, iothread->thread_pool_max); } - virXMLFormatElement(&childrenBuf, "iothread", &attrBuf, NULL); + if (iothread->set_poll_max_ns) + virBufferAsprintf(&pollAttrBuf, " max='%llu'", iothread->poll_max_ns); + + if (iothread->set_poll_grow) + virBufferAsprintf(&pollAttrBuf, " grow='%llu'", iothread->poll_grow); + + if (iothread->set_poll_shrink) + virBufferAsprintf(&pollAttrBuf, " shrink='%llu'", iothread->poll_shrink); + + virXMLFormatElement(&iothreadChildBuf, "poll", &pollAttrBuf, NULL); + + virXMLFormatElement(&childrenBuf, "iothread", &attrBuf, &iothreadChildBuf); } virXMLFormatElement(buf, "iothreadids", NULL, &childrenBuf); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2a8fc6f90d..88aef29912 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2715,6 +2715,13 @@ struct _virDomainIOThreadIDDef { virDomainThreadSchedParam sched; + unsigned long long poll_max_ns; + bool set_poll_max_ns; + unsigned long long poll_grow; + bool set_poll_grow; + unsigned long long poll_shrink; + bool set_poll_shrink; + int thread_pool_min; int thread_pool_max; }; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 6158ed79ac..57fb4a5e33 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -885,6 +885,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/iothreads-ids-pool-sizes.xml b/tests/qemuxml2argvdata/iothreads-ids-pool-sizes.xml index df4b291a7a..63fb4a52f6 100644 --- a/tests/qemuxml2argvdata/iothreads-ids-pool-sizes.xml +++ b/tests/qemuxml2argvdata/iothreads-ids-pool-sizes.xml @@ -7,9 +7,15 @@ 5 - - - + + + + + + + + +