mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-30 13:37:17 +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="6"/>
|
||||||
<iothread id="8" thread_pool_min="2" thread_pool_max="32"/>
|
<iothread id="8" thread_pool_min="2" thread_pool_max="32"/>
|
||||||
</iothreadids>
|
</iothreadids>
|
||||||
|
<defaultiothread thread_pool_min="8" thread_pool_max="16">
|
||||||
...
|
...
|
||||||
</domain>
|
</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
|
``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,
|
of worker threads for given IOThread. While the former can be value of zero,
|
||||||
the latter can't. :since:`Since 8.5.0`
|
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
|
CPU Tuning
|
||||||
|
@ -3825,6 +3825,8 @@ void virDomainDefFree(virDomainDef *def)
|
|||||||
|
|
||||||
virDomainIOThreadIDDefArrayFree(def->iothreadids, def->niothreadids);
|
virDomainIOThreadIDDefArrayFree(def->iothreadids, def->niothreadids);
|
||||||
|
|
||||||
|
g_free(def->defaultIOThread);
|
||||||
|
|
||||||
virBitmapFree(def->cputune.emulatorpin);
|
virBitmapFree(def->cputune.emulatorpin);
|
||||||
g_free(def->cputune.emulatorsched);
|
g_free(def->cputune.emulatorsched);
|
||||||
|
|
||||||
@ -17017,6 +17019,7 @@ virDomainIdmapDefParseXML(xmlXPathContextPtr ctxt,
|
|||||||
* <iothread id='5'/>
|
* <iothread id='5'/>
|
||||||
* <iothread id='7'/>
|
* <iothread id='7'/>
|
||||||
* </iothreadids>
|
* </iothreadids>
|
||||||
|
* <defaultiothread thread_pool_min="8" thread_pool_max="8"/>
|
||||||
*/
|
*/
|
||||||
static virDomainIOThreadIDDef *
|
static virDomainIOThreadIDDef *
|
||||||
virDomainIOThreadIDDefParseXML(xmlNodePtr node)
|
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
|
static int
|
||||||
virDomainDefParseIOThreads(virDomainDef *def,
|
virDomainDefParseIOThreads(virDomainDef *def,
|
||||||
xmlXPathContextPtr ctxt)
|
xmlXPathContextPtr ctxt)
|
||||||
@ -17059,6 +17094,9 @@ virDomainDefParseIOThreads(virDomainDef *def,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainDefaultIOThreadDefParse(def, ctxt) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* Extract any iothread id's defined */
|
/* Extract any iothread id's defined */
|
||||||
if ((n = virXPathNodeSet("./iothreadids/iothread", ctxt, &nodes)) < 0)
|
if ((n = virXPathNodeSet("./iothreadids/iothread", ctxt, &nodes)) < 0)
|
||||||
return -1;
|
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
|
static void
|
||||||
virDomainDefIOThreadsFormat(virBuffer *buf,
|
virDomainDefIOThreadsFormat(virBuffer *buf,
|
||||||
const virDomainDef *def)
|
const virDomainDef *def)
|
||||||
@ -27641,6 +27702,8 @@ virDomainDefIOThreadsFormat(virBuffer *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
virXMLFormatElement(buf, "iothreadids", NULL, &childrenBuf);
|
virXMLFormatElement(buf, "iothreadids", NULL, &childrenBuf);
|
||||||
|
|
||||||
|
virDomainDefaultIOThreadDefFormat(buf, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2655,6 +2655,12 @@ void virDomainIOThreadIDDefFree(virDomainIOThreadIDDef *def);
|
|||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainIOThreadIDDef, virDomainIOThreadIDDefFree);
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainIOThreadIDDef, virDomainIOThreadIDDefFree);
|
||||||
|
|
||||||
|
|
||||||
|
struct _virDomainDefaultIOThreadDef {
|
||||||
|
int thread_pool_min;
|
||||||
|
int thread_pool_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct _virDomainCputune {
|
struct _virDomainCputune {
|
||||||
unsigned long long shares;
|
unsigned long long shares;
|
||||||
bool sharesSpecified;
|
bool sharesSpecified;
|
||||||
@ -2863,6 +2869,8 @@ struct _virDomainDef {
|
|||||||
size_t niothreadids;
|
size_t niothreadids;
|
||||||
virDomainIOThreadIDDef **iothreadids;
|
virDomainIOThreadIDDef **iothreadids;
|
||||||
|
|
||||||
|
virDomainDefaultIOThreadDef *defaultIOThread;
|
||||||
|
|
||||||
virDomainCputune cputune;
|
virDomainCputune cputune;
|
||||||
|
|
||||||
virDomainResctrlDef **resctrls;
|
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
|
static int
|
||||||
virDomainDefValidateIOThreads(const virDomainDef *def)
|
virDomainDefValidateIOThreads(const virDomainDef *def)
|
||||||
{
|
{
|
||||||
@ -1724,19 +1744,16 @@ virDomainDefValidateIOThreads(const virDomainDef *def)
|
|||||||
for (i = 0; i < def->niothreadids; i++) {
|
for (i = 0; i < def->niothreadids; i++) {
|
||||||
virDomainIOThreadIDDef *iothread = def->iothreadids[i];
|
virDomainIOThreadIDDef *iothread = def->iothreadids[i];
|
||||||
|
|
||||||
if (iothread->thread_pool_max == 0) {
|
if (virDomainDefValidateIOThreadsThreadPool(iothread->thread_pool_min,
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
iothread->thread_pool_max) < 0)
|
||||||
_("thread_pool_max must be a positive integer"));
|
|
||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,6 +844,21 @@
|
|||||||
</element>
|
</element>
|
||||||
</optional>
|
</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>
|
<optional>
|
||||||
<ref name="blkiotune"/>
|
<ref name="blkiotune"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
@ -142,6 +142,8 @@ typedef struct _virDomainIOMMUDef virDomainIOMMUDef;
|
|||||||
|
|
||||||
typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef;
|
typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef;
|
||||||
|
|
||||||
|
typedef struct _virDomainDefaultIOThreadDef virDomainDefaultIOThreadDef;
|
||||||
|
|
||||||
typedef struct _virDomainIdMapDef virDomainIdMapDef;
|
typedef struct _virDomainIdMapDef virDomainIdMapDef;
|
||||||
|
|
||||||
typedef struct _virDomainIdMapEntry virDomainIdMapEntry;
|
typedef struct _virDomainIdMapEntry virDomainIdMapEntry;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
<iothread id='3'/>
|
<iothread id='3'/>
|
||||||
<iothread id='5'/>
|
<iothread id='5'/>
|
||||||
</iothreadids>
|
</iothreadids>
|
||||||
|
<defaultiothread thread_pool_min='8' thread_pool_max='16'/>
|
||||||
<os>
|
<os>
|
||||||
<type arch='x86_64' machine='q35'>hvm</type>
|
<type arch='x86_64' machine='q35'>hvm</type>
|
||||||
<boot dev='hd'/>
|
<boot dev='hd'/>
|
||||||
|
Loading…
Reference in New Issue
Block a user