mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
conf: Introduce <defaultiothread/>
As of v7.0.0-877-g70ac26b9e5 QEMU exposes its default event loop for devices with no IOThread assigned as an QMP object. In the very next commit (v7.0.0-878-g71ad4713cc) it was extended for thread-pool-min and thread-pool-max attributes. Expose them under new <defaultiothread/> element. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
7162cee68a
commit
3e4bebb9d1
@ -677,6 +677,7 @@ host/guest with many LUNs. :since:`Since 1.2.8 (QEMU only)`
|
||||
<iothread id="6"/>
|
||||
<iothread id="8" thread_pool_min="2" thread_pool_max="32"/>
|
||||
</iothreadids>
|
||||
<defaultiothread thread_pool_min="8" thread_pool_max="16">
|
||||
...
|
||||
</domain>
|
||||
|
||||
@ -700,6 +701,16 @@ 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`
|
||||
``defaultiothread``
|
||||
This element represents the default event loop within hypervisor, where I/O
|
||||
requests from devices not assigned to a specific IOThread are processed.
|
||||
The element then can have ``thread_pool_min`` and/or ``thread_pool_max``
|
||||
attributes, which control the lower and upper boundary for number of worker
|
||||
threads of the default event loop. Emulator might be multithreaded and spawn
|
||||
so called worker threads on demand. In general neither of these attributes
|
||||
should be set (leaving the emulator use its own default values), unless the
|
||||
emulator runs in a real time workload and thus can't afford unpredictability
|
||||
of time it takes to spawn new worker threads. :since:`Since 8.5.0`
|
||||
|
||||
|
||||
CPU Tuning
|
||||
|
@ -3825,6 +3825,8 @@ void virDomainDefFree(virDomainDef *def)
|
||||
|
||||
virDomainIOThreadIDDefArrayFree(def->iothreadids, def->niothreadids);
|
||||
|
||||
g_free(def->defaultIOThread);
|
||||
|
||||
virBitmapFree(def->cputune.emulatorpin);
|
||||
g_free(def->cputune.emulatorsched);
|
||||
|
||||
@ -17017,6 +17019,7 @@ virDomainIdmapDefParseXML(xmlXPathContextPtr ctxt,
|
||||
* <iothread id='5'/>
|
||||
* <iothread id='7'/>
|
||||
* </iothreadids>
|
||||
* <defaultiothread thread_pool_min="8" thread_pool_max="8"/>
|
||||
*/
|
||||
static virDomainIOThreadIDDef *
|
||||
virDomainIOThreadIDDefParseXML(xmlNodePtr node)
|
||||
@ -17042,6 +17045,38 @@ virDomainIOThreadIDDefParseXML(xmlNodePtr node)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDefaultIOThreadDefParse(virDomainDef *def,
|
||||
xmlXPathContextPtr ctxt)
|
||||
{
|
||||
xmlNodePtr node = NULL;
|
||||
g_autofree virDomainDefaultIOThreadDef *thrd = NULL;
|
||||
|
||||
node = virXPathNode("./defaultiothread", ctxt);
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
thrd = g_new0(virDomainDefaultIOThreadDef, 1);
|
||||
|
||||
if (virXMLPropInt(node, "thread_pool_min", 10,
|
||||
VIR_XML_PROP_NONNEGATIVE,
|
||||
&thrd->thread_pool_min, -1) < 0)
|
||||
return -1;
|
||||
|
||||
if (virXMLPropInt(node, "thread_pool_max", 10,
|
||||
VIR_XML_PROP_NONNEGATIVE,
|
||||
&thrd->thread_pool_max, -1) < 0)
|
||||
return -1;
|
||||
|
||||
if (thrd->thread_pool_min == -1 &&
|
||||
thrd->thread_pool_max == -1)
|
||||
return 0;
|
||||
|
||||
def->defaultIOThread = g_steal_pointer(&thrd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDefParseIOThreads(virDomainDef *def,
|
||||
xmlXPathContextPtr ctxt)
|
||||
@ -17059,6 +17094,9 @@ virDomainDefParseIOThreads(virDomainDef *def,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virDomainDefaultIOThreadDefParse(def, ctxt) < 0)
|
||||
return -1;
|
||||
|
||||
/* Extract any iothread id's defined */
|
||||
if ((n = virXPathNodeSet("./iothreadids/iothread", ctxt, &nodes)) < 0)
|
||||
return -1;
|
||||
@ -27604,6 +27642,29 @@ virDomainDefIothreadShouldFormat(const virDomainDef *def)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainDefaultIOThreadDefFormat(virBuffer *buf,
|
||||
const virDomainDef *def)
|
||||
{
|
||||
virBuffer attrBuf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
if (!def->defaultIOThread)
|
||||
return;
|
||||
|
||||
if (def->defaultIOThread->thread_pool_min >= 0) {
|
||||
virBufferAsprintf(&attrBuf, " thread_pool_min='%d'",
|
||||
def->defaultIOThread->thread_pool_min);
|
||||
}
|
||||
|
||||
if (def->defaultIOThread->thread_pool_max >= 0) {
|
||||
virBufferAsprintf(&attrBuf, " thread_pool_max='%d'",
|
||||
def->defaultIOThread->thread_pool_max);
|
||||
}
|
||||
|
||||
virXMLFormatElement(buf, "defaultiothread", &attrBuf, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virDomainDefIOThreadsFormat(virBuffer *buf,
|
||||
const virDomainDef *def)
|
||||
@ -27641,6 +27702,8 @@ virDomainDefIOThreadsFormat(virBuffer *buf,
|
||||
}
|
||||
|
||||
virXMLFormatElement(buf, "iothreadids", NULL, &childrenBuf);
|
||||
|
||||
virDomainDefaultIOThreadDefFormat(buf, def);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2655,6 +2655,12 @@ void virDomainIOThreadIDDefFree(virDomainIOThreadIDDef *def);
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainIOThreadIDDef, virDomainIOThreadIDDefFree);
|
||||
|
||||
|
||||
struct _virDomainDefaultIOThreadDef {
|
||||
int thread_pool_min;
|
||||
int thread_pool_max;
|
||||
};
|
||||
|
||||
|
||||
struct _virDomainCputune {
|
||||
unsigned long long shares;
|
||||
bool sharesSpecified;
|
||||
@ -2863,6 +2869,8 @@ struct _virDomainDef {
|
||||
size_t niothreadids;
|
||||
virDomainIOThreadIDDef **iothreadids;
|
||||
|
||||
virDomainDefaultIOThreadDef *defaultIOThread;
|
||||
|
||||
virDomainCputune cputune;
|
||||
|
||||
virDomainResctrlDef **resctrls;
|
||||
|
@ -1716,6 +1716,26 @@ virDomainDefFSValidate(const virDomainDef *def)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDefValidateIOThreadsThreadPool(int thread_pool_min,
|
||||
int thread_pool_max)
|
||||
{
|
||||
if (thread_pool_max == 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("thread_pool_max must be a positive integer"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (thread_pool_min > thread_pool_max) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("thread_pool_min must be smaller or equal to thread_pool_max"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDefValidateIOThreads(const virDomainDef *def)
|
||||
{
|
||||
@ -1724,19 +1744,16 @@ virDomainDefValidateIOThreads(const virDomainDef *def)
|
||||
for (i = 0; i < def->niothreadids; i++) {
|
||||
virDomainIOThreadIDDef *iothread = def->iothreadids[i];
|
||||
|
||||
if (iothread->thread_pool_max == 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("thread_pool_max must be a positive integer"));
|
||||
if (virDomainDefValidateIOThreadsThreadPool(iothread->thread_pool_min,
|
||||
iothread->thread_pool_max) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iothread->thread_pool_min > iothread->thread_pool_max) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("thread_pool_min must be smaller or equal to thread_pool_max"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (def->defaultIOThread &&
|
||||
virDomainDefValidateIOThreadsThreadPool(def->defaultIOThread->thread_pool_min,
|
||||
def->defaultIOThread->thread_pool_max) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -844,6 +844,21 @@
|
||||
</element>
|
||||
</optional>
|
||||
|
||||
<optional>
|
||||
<element name="defaultiothread">
|
||||
<optional>
|
||||
<attribute name="thread_pool_min">
|
||||
<ref name="unsignedInt"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="thread_pool_max">
|
||||
<ref name="unsignedInt"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</optional>
|
||||
|
||||
<optional>
|
||||
<ref name="blkiotune"/>
|
||||
</optional>
|
||||
|
@ -142,6 +142,8 @@ typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
|
||||
|
||||
typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef;
|
||||
|
||||
typedef struct _virDomainDefaultIOThreadDef virDomainDefaultIOThreadDef;
|
||||
|
||||
typedef struct _virDomainIdMapDef virDomainIdMapDef;
|
||||
|
||||
typedef struct _virDomainIdMapEntry virDomainIdMapEntry;
|
||||
|
@ -12,6 +12,7 @@
|
||||
<iothread id='3'/>
|
||||
<iothread id='5'/>
|
||||
</iothreadids>
|
||||
<defaultiothread thread_pool_min='8' thread_pool_max='16'/>
|
||||
<os>
|
||||
<type arch='x86_64' machine='q35'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
|
Loading…
Reference in New Issue
Block a user