Use the configured iothread poll-weight value when interacting with
QEMU.
This wires the new setting into command line generation, monitor data
parsing, driver-side parameter handling, and capability-based
validation. Remove the break from the iothread validation loop because
the loop now also checks poll-weight on every iothread.
Signed-off-by: Jaehoon Kim <jhkim@linux.ibm.com>
---
include/libvirt/libvirt-domain.h | 26 +++++++++
src/qemu/qemu_command.c | 18 +++++-
src/qemu/qemu_driver.c | 38 ++++++++++++
src/qemu/qemu_monitor.h | 2 +
src/qemu/qemu_monitor_json.c | 18 ++++++
src/qemu/qemu_validate.c | 10 +++-
...othreads-ids-poll-weight.x86_64-11.0.0.err | 1 +
...threads-ids-poll-weight.x86_64-latest.args | 40 +++++++++++++
...othreads-ids-poll-weight.x86_64-latest.xml | 58 +++++++++++++++++++
.../iothreads-ids-poll-weight.xml | 58 +++++++++++++++++++
tests/qemuxmlconftest.c | 2 +
11 files changed, 267 insertions(+), 4 deletions(-)
create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-11.0.0.err
create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.xml
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 5b67f8f897..f49aa1c136 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -2748,6 +2748,22 @@ int virDomainDelIOThread(virDomainPtr domain,
*/
# define VIR_DOMAIN_IOTHREAD_POLL_SHRINK "poll_shrink"
+/**
+ * VIR_DOMAIN_IOTHREAD_POLL_WEIGHT:
+ *
+ * This provides a shift value for the adaptive polling algorithm to control
+ * how much the most recent event interval affects the next polling duration
+ * calculation. Larger values decrease the weight of the current interval,
+ * enabling more gradual adjustments. Valid range is [0, 63]. A value of 0
+ * lets the hypervisor select a default weight (typically 3, meaning the
+ * current interval contributes approximately 1/8 to the weighted average).
+ *
+ * Accepted type is VIR_TYPED_PARAM_UINT.
+ *
+ * Since: 12.6.0
+ */
+# define VIR_DOMAIN_IOTHREAD_POLL_WEIGHT "poll_weight"
+
/**
* VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN:
*
@@ -4330,6 +4346,16 @@ struct _virDomainStatsRecord {
*/
# define VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_SHRINK ".poll-shrink"
+/**
+ * VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_WEIGHT:
+ *
+ * Polling weight factor as an unsigned int. This shift value controls how
+ * much the most recent event interval affects adaptive polling calculations.
+ * A 0 (zero) indicates the hypervisor's default weight is used.
+ *
+ * Since: 12.6.0
+ */
+# define VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_WEIGHT ".poll-weight"
/**
* VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_COUNT:
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 95e2ea9a6b..b351059fc1 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7659,7 +7659,8 @@ qemuBuildMemCommandLine(virCommand *cmd,
static int
qemuBuildIOThreadCommandLine(virCommand *cmd,
- const virDomainDef *def)
+ const virDomainDef *def,
+ virQEMUCaps *qemuCaps)
{
size_t i;
@@ -7694,6 +7695,19 @@ qemuBuildIOThreadCommandLine(virCommand *cmd,
NULL) < 0)
return -1;
+ if (iothread->set_poll_weight) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_IOTHREAD_POLL_WEIGHT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("poll-weight is not supported by this QEMU binary"));
+ return -1;
+ }
+
+ if (virJSONValueObjectAdd(&props,
+ "u:poll-weight", iothread->poll_weight,
+ NULL) < 0)
+ return -1;
+ }
+
if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
return -1;
}
@@ -10903,7 +10917,7 @@ qemuBuildCommandLine(virDomainObj *vm,
if (qemuBuildSmpCommandLine(cmd, def, qemuCaps) < 0)
return NULL;
- if (qemuBuildIOThreadCommandLine(cmd, def) < 0)
+ if (qemuBuildIOThreadCommandLine(cmd, def, qemuCaps) < 0)
return NULL;
if (qemuBuildThrottleGroupCommandLine(cmd, def) < 0)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index bdc0cff66a..1afd6e83ba 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5261,6 +5261,11 @@ qemuDomainHotplugModIOThreadIDDef(virDomainIOThreadIDDef *def,
def->set_poll_shrink = true;
}
+ if (mondef.set_poll_weight) {
+ def->poll_weight = mondef.poll_weight;
+ def->set_poll_weight = true;
+ }
+
if (mondef.set_thread_pool_min)
def->thread_pool_min = mondef.thread_pool_min;
@@ -5353,6 +5358,11 @@ qemuDomainHotplugDelIOThread(virDomainObj *vm,
* necessary. If a 0 (zero) value is provided, QEMU resets the polling
* interval to 0 (zero) allowing the poll-grow to manipulate the time.
*
+ * - "poll-weight" - weight shift value used by the adaptive polling algorithm
+ * to determine how much the most recent event interval influences the
+ * next interval calculation. Accepted range is [0, 63]. If a 0 (zero)
+ * value is provided, QEMU uses its default weight.
+ *
* QEMU keeps track of the polling time elapsed and may grow or shrink the
* its polling interval based upon its heuristic algorithm. It is possible
* that calculations determine that it has found a "sweet spot" and no
@@ -5388,6 +5398,20 @@ qemuDomainIOThreadParseParams(virTypedParameterPtr params,
if (rc == 1)
iothread->set_poll_shrink = true;
+ if ((rc = virTypedParamsGetUInt(params, nparams,
+ VIR_DOMAIN_IOTHREAD_POLL_WEIGHT,
+ &iothread->poll_weight)) < 0)
+ return -1;
+ if (rc == 1) {
+ if (iothread->poll_weight > 63) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("poll-weight value %1$u is out of range [0, 63]"),
+ iothread->poll_weight);
+ return -1;
+ }
+ iothread->set_poll_weight = true;
+ }
+
if ((rc = virTypedParamsGetInt(params, nparams,
VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN,
&iothread->thread_pool_min)) < 0)
@@ -5586,6 +5610,13 @@ qemuDomainChgIOThread(virQEMUDriver *driver,
if (qemuDomainIOThreadValidate(iothreaddef, iothread, true) < 0)
goto endjob;
+ if (iothread.set_poll_weight &&
+ !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_IOTHREAD_POLL_WEIGHT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("poll-weight is not supported by this QEMU binary"));
+ goto endjob;
+ }
+
if (qemuDomainHotplugModIOThread(vm, iothread) < 0)
goto endjob;
@@ -5716,6 +5747,8 @@ qemuDomainSetIOThreadParams(virDomainPtr dom,
VIR_TYPED_PARAM_UNSIGNED,
VIR_DOMAIN_IOTHREAD_POLL_SHRINK,
VIR_TYPED_PARAM_UNSIGNED,
+ VIR_DOMAIN_IOTHREAD_POLL_WEIGHT,
+ VIR_TYPED_PARAM_UINT,
VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN,
VIR_TYPED_PARAM_INT,
VIR_DOMAIN_IOTHREAD_THREAD_POOL_MAX,
@@ -18380,6 +18413,11 @@ qemuDomainGetStatsIOThread(virQEMUDriver *driver G_GNUC_UNUSED,
VIR_DOMAIN_STATS_IOTHREAD_PREFIX "%u" VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_SHRINK,
iothreads[i]->iothread_id);
}
+ if (iothreads[i]->set_poll_weight) {
+ virTypedParamListAddUInt(params, iothreads[i]->poll_weight,
+ VIR_DOMAIN_STATS_IOTHREAD_PREFIX "%u" VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_WEIGHT,
+ iothreads[i]->iothread_id);
+ }
}
for (i = 0; i < niothreads; i++)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index c2afb580e4..e73be4e263 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1583,11 +1583,13 @@ struct _qemuMonitorIOThreadInfo {
unsigned long long poll_max_ns;
unsigned long long poll_grow;
unsigned long long poll_shrink;
+ unsigned int poll_weight;
int thread_pool_min;
int thread_pool_max;
bool set_poll_max_ns;
bool set_poll_grow;
bool set_poll_shrink;
+ bool set_poll_weight;
bool set_thread_pool_min;
bool set_thread_pool_max;
};
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 21f4d613b7..c88f74c10b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -7202,6 +7202,11 @@ qemuMonitorJSONGetIOThreads(qemuMonitor *mon,
virJSONValueObjectGetNumberUlong(child, "poll-shrink",
&info->poll_shrink) == 0)
info->poll_valid = true;
+
+ /* poll-weight is optional, only present on newer QEMU */
+ if (virJSONValueObjectGetNumberUint(child, "poll-weight",
+ &info->poll_weight) == 0)
+ info->set_poll_weight = true;
}
*niothreads = n;
@@ -7243,6 +7248,19 @@ qemuMonitorJSONSetIOThread(qemuMonitor *mon,
#undef VIR_IOTHREAD_SET_PROP_UL
+#define VIR_IOTHREAD_SET_PROP_UINT(propName, propVal) \
+ if (iothreadInfo->set_##propVal) { \
+ memset(&prop, 0, sizeof(prop)); \
+ prop.type = QEMU_MONITOR_OBJECT_PROPERTY_UINT; \
+ prop.val.ui = iothreadInfo->propVal; \
+ if (qemuMonitorJSONSetObjectProperty(mon, path, propName, &prop) < 0) \
+ return -1; \
+ }
+
+ VIR_IOTHREAD_SET_PROP_UINT("poll-weight", poll_weight);
+
+#undef VIR_IOTHREAD_SET_PROP_UINT
+
if (iothreadInfo->set_thread_pool_min &&
iothreadInfo->set_thread_pool_max) {
int curr_max = -1;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 439d4b1916..5a770a800f 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -500,9 +500,15 @@ qemuValidateDomainDefIOThreads(const virDomainDef *def,
for (i = 0; i < def->niothreadids; i++) {
virDomainIOThreadIDDef *iothread = def->iothreadids[i];
- if (iothread->thread_pool_min != -1 || iothread->thread_pool_max != -1) {
+ if (iothread->thread_pool_min != -1 || iothread->thread_pool_max != -1)
needsThreadPoolCap = true;
- break;
+
+ /* poll-weight requires QEMU_CAPS_IOTHREAD_POLL_WEIGHT */
+ if (iothread->set_poll_weight &&
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_IOTHREAD_POLL_WEIGHT)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("poll-weight is not supported by this QEMU binary"));
+ return -1;
}
}
diff --git a/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-11.0.0.err b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-11.0.0.err
new file mode 100644
index 0000000000..1cc4109f27
--- /dev/null
+++ b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-11.0.0.err
@@ -0,0 +1 @@
+unsupported configuration: poll-weight is not supported by this QEMU binary
diff --git a/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.args b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.args
new file mode 100644
index 0000000000..d73060ad46
--- /dev/null
+++ b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.args
@@ -0,0 +1,40 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
+-machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=219136k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
+-overcommit mem-lock=off \
+-smp 4,sockets=4,cores=1,threads=1 \
+-object '{"qom-type":"iothread","id":"iothread1","poll-max-ns":123000,"poll-grow":456,"poll-shrink":789,"poll-weight":3}' \
+-object '{"qom-type":"iothread","id":"iothread2","poll-weight":0}' \
+-object '{"qom-type":"iothread","id":"iothread3","poll-max-ns":32000,"poll-weight":63}' \
+-object '{"qom-type":"iothread","id":"iothread4","poll-max-ns":32000,"poll-grow":2,"poll-shrink":2}' \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=@mon-fd@,server=on,wait=off \
+-object '{"qom-type":"monitor-qmp","id":"monitor","chardev":"charmonitor"}' \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \
+-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \
+-device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.xml b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.xml
new file mode 100644
index 0000000000..1134d9ffdd
--- /dev/null
+++ b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.xml
@@ -0,0 +1,58 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>4</vcpu>
+ <iothreads>4</iothreads>
+ <iothreadids>
+ <iothread id='1'>
+ <poll max='123000' grow='456' shrink='789' weight='3'/>
+ </iothread>
+ <iothread id='2'>
+ <poll weight='0'/>
+ </iothread>
+ <iothread id='3'>
+ <poll max='32000' weight='63'/>
+ </iothread>
+ <iothread id='4'>
+ <poll max='32000' grow='2' shrink='2'/>
+ </iothread>
+ </iothreadids>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x9'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/iothreads-ids-poll-weight.xml b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.xml
new file mode 100644
index 0000000000..1134d9ffdd
--- /dev/null
+++ b/tests/qemuxmlconfdata/iothreads-ids-poll-weight.xml
@@ -0,0 +1,58 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>4</vcpu>
+ <iothreads>4</iothreads>
+ <iothreadids>
+ <iothread id='1'>
+ <poll max='123000' grow='456' shrink='789' weight='3'/>
+ </iothread>
+ <iothread id='2'>
+ <poll weight='0'/>
+ </iothread>
+ <iothread id='3'>
+ <poll max='32000' weight='63'/>
+ </iothread>
+ <iothread id='4'>
+ <poll max='32000' grow='2' shrink='2'/>
+ </iothread>
+ </iothreadids>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x8'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x9'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index df0b257cbe..682aaad74f 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2333,6 +2333,8 @@ mymain(void)
DO_TEST_CAPS_LATEST("iothreads-ids");
DO_TEST_CAPS_LATEST("iothreads-ids-partial");
DO_TEST_CAPS_LATEST("iothreads-ids-pool-sizes");
+ DO_TEST_CAPS_LATEST("iothreads-ids-poll-weight");
+ DO_TEST_CAPS_VER_PARSE_ERROR("iothreads-ids-poll-weight", "11.0.0");
DO_TEST_CAPS_LATEST("iothreads-disk");
DO_TEST_CAPS_LATEST("iothreads-virtio-scsi-pci");
DO_TEST_CAPS_LATEST("iothreads-virtio-scsi-mapping");
--
2.54.0
On Wed, Jul 22, 2026 at 13:52:12 -0500, Jaehoon Kim wrote:
> Use the configured iothread poll-weight value when interacting with
> QEMU.
>
> This wires the new setting into command line generation, monitor data
> parsing, driver-side parameter handling, and capability-based
> validation. Remove the break from the iothread validation loop because
> the loop now also checks poll-weight on every iothread.
>
> Signed-off-by: Jaehoon Kim <jhkim@linux.ibm.com>
> ---
> include/libvirt/libvirt-domain.h | 26 +++++++++
> src/qemu/qemu_command.c | 18 +++++-
> src/qemu/qemu_driver.c | 38 ++++++++++++
> src/qemu/qemu_monitor.h | 2 +
> src/qemu/qemu_monitor_json.c | 18 ++++++
> src/qemu/qemu_validate.c | 10 +++-
> ...othreads-ids-poll-weight.x86_64-11.0.0.err | 1 +
> ...threads-ids-poll-weight.x86_64-latest.args | 40 +++++++++++++
> ...othreads-ids-poll-weight.x86_64-latest.xml | 58 +++++++++++++++++++
> .../iothreads-ids-poll-weight.xml | 58 +++++++++++++++++++
> tests/qemuxmlconftest.c | 2 +
> 11 files changed, 267 insertions(+), 4 deletions(-)
> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-11.0.0.err
> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.args
> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.xml
> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.xml
>
> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
> index 5b67f8f897..f49aa1c136 100644
> --- a/include/libvirt/libvirt-domain.h
> +++ b/include/libvirt/libvirt-domain.h
> @@ -2748,6 +2748,22 @@ int virDomainDelIOThread(virDomainPtr domain,
> */
> # define VIR_DOMAIN_IOTHREAD_POLL_SHRINK "poll_shrink"
>
> +/**
> + * VIR_DOMAIN_IOTHREAD_POLL_WEIGHT:
> + *
> + * This provides a shift value for the adaptive polling algorithm to control
> + * how much the most recent event interval affects the next polling duration
> + * calculation. Larger values decrease the weight of the current interval,
> + * enabling more gradual adjustments. Valid range is [0, 63]. A value of 0
> + * lets the hypervisor select a default weight (typically 3, meaning the
Okay, so 0 is a special value. The parser doesn't treat it as a special
value. With this impl it would mean that there are 2 manifestation of
the same "hypervisor default" setting. One is if the 'weight' attribute
is missing completely. Second one is if it's explicitly set to '0'.
I'm not a fan of having 2 manifestations of the default but I don't have
a better sugestion either.
> + * current interval contributes approximately 1/8 to the weighted average).
> + *
> + * Accepted type is VIR_TYPED_PARAM_UINT.
> + *
> + * Since: 12.6.0
This will have to be 12.7.0, the tree is in freeze for the 12.6.0
release already.
> + */
> +# define VIR_DOMAIN_IOTHREAD_POLL_WEIGHT "poll_weight"
> +
> /**
> * VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN:
> *
> @@ -4330,6 +4346,16 @@ struct _virDomainStatsRecord {
> */
> # define VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_SHRINK ".poll-shrink"
>
> +/**
> + * VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_WEIGHT:
> + *
> + * Polling weight factor as an unsigned int. This shift value controls how
> + * much the most recent event interval affects adaptive polling calculations.
> + * A 0 (zero) indicates the hypervisor's default weight is used.
> + *
> + * Since: 12.6.0
ditto
So here I presume the presence of this field will be based on whether
qemu supports this feature (since the stats will be filled from the
return from qemu) so 0 in fact can be shown even without config. That
does make sense for the getter.
> + */
> +# define VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_WEIGHT ".poll-weight"
>
> /**
> * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_COUNT:
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 95e2ea9a6b..b351059fc1 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -7659,7 +7659,8 @@ qemuBuildMemCommandLine(virCommand *cmd,
>
> static int
> qemuBuildIOThreadCommandLine(virCommand *cmd,
> - const virDomainDef *def)
> + const virDomainDef *def,
> + virQEMUCaps *qemuCaps)
> {
> size_t i;
>
> @@ -7694,6 +7695,19 @@ qemuBuildIOThreadCommandLine(virCommand *cmd,
> NULL) < 0)
> return -1;
>
> + if (iothread->set_poll_weight) {
> + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_IOTHREAD_POLL_WEIGHT)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("poll-weight is not supported by this QEMU binary"));
> + return -1;
> + }
This check is dead code since qemuValidateDomainDefIOThreads is called
before this happens in all cases.
> +
> + if (virJSONValueObjectAdd(&props,
> + "u:poll-weight", iothread->poll_weight,
> + NULL) < 0)
> + return -1;
> + }
> +
> if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
> return -1;
> }
[...]
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index bdc0cff66a..1afd6e83ba 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -5261,6 +5261,11 @@ qemuDomainHotplugModIOThreadIDDef(virDomainIOThreadIDDef *def,
> def->set_poll_shrink = true;
> }
>
> + if (mondef.set_poll_weight) {
> + def->poll_weight = mondef.poll_weight;
> + def->set_poll_weight = true;
> + }
> +
> if (mondef.set_thread_pool_min)
> def->thread_pool_min = mondef.thread_pool_min;
>
> @@ -5353,6 +5358,11 @@ qemuDomainHotplugDelIOThread(virDomainObj *vm,
> * necessary. If a 0 (zero) value is provided, QEMU resets the polling
> * interval to 0 (zero) allowing the poll-grow to manipulate the time.
> *
> + * - "poll-weight" - weight shift value used by the adaptive polling algorithm
> + * to determine how much the most recent event interval influences the
> + * next interval calculation. Accepted range is [0, 63]. If a 0 (zero)
> + * value is provided, QEMU uses its default weight.
> + *
> * QEMU keeps track of the polling time elapsed and may grow or shrink the
> * its polling interval based upon its heuristic algorithm. It is possible
> * that calculations determine that it has found a "sweet spot" and no
> @@ -5388,6 +5398,20 @@ qemuDomainIOThreadParseParams(virTypedParameterPtr params,
> if (rc == 1)
> iothread->set_poll_shrink = true;
>
> + if ((rc = virTypedParamsGetUInt(params, nparams,
> + VIR_DOMAIN_IOTHREAD_POLL_WEIGHT,
> + &iothread->poll_weight)) < 0)
> + return -1;
> + if (rc == 1) {
> + if (iothread->poll_weight > 63) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("poll-weight value %1$u is out of range [0, 63]"),
> + iothread->poll_weight);
> + return -1;
> + }
> + iothread->set_poll_weight = true;
> + }
> +
> if ((rc = virTypedParamsGetInt(params, nparams,
> VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN,
> &iothread->thread_pool_min)) < 0)
[...]
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index c2afb580e4..e73be4e263 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -1583,11 +1583,13 @@ struct _qemuMonitorIOThreadInfo {
> unsigned long long poll_max_ns;
> unsigned long long poll_grow;
> unsigned long long poll_shrink;
> + unsigned int poll_weight;
> int thread_pool_min;
> int thread_pool_max;
> bool set_poll_max_ns;
> bool set_poll_grow;
> bool set_poll_shrink;
> + bool set_poll_weight;
> bool set_thread_pool_min;
> bool set_thread_pool_max;
> };
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 21f4d613b7..c88f74c10b 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -7202,6 +7202,11 @@ qemuMonitorJSONGetIOThreads(qemuMonitor *mon,
> virJSONValueObjectGetNumberUlong(child, "poll-shrink",
> &info->poll_shrink) == 0)
> info->poll_valid = true;
> +
> + /* poll-weight is optional, only present on newer QEMU */
> + if (virJSONValueObjectGetNumberUint(child, "poll-weight",
> + &info->poll_weight) == 0)
> + info->set_poll_weight = true;
> }
>
> *niothreads = n;
I'd prefer if this getter code changes are separated. The monitor can
fetch the values and not use them. Maybe even the stats entries can be
added before this is set.
> @@ -7243,6 +7248,19 @@ qemuMonitorJSONSetIOThread(qemuMonitor *mon,
>
> #undef VIR_IOTHREAD_SET_PROP_UL
>
> +#define VIR_IOTHREAD_SET_PROP_UINT(propName, propVal) \
> + if (iothreadInfo->set_##propVal) { \
> + memset(&prop, 0, sizeof(prop)); \
> + prop.type = QEMU_MONITOR_OBJECT_PROPERTY_UINT; \
> + prop.val.ui = iothreadInfo->propVal; \
> + if (qemuMonitorJSONSetObjectProperty(mon, path, propName, &prop) < 0) \
> + return -1; \
> + }
> +
> + VIR_IOTHREAD_SET_PROP_UINT("poll-weight", poll_weight);
> +
> +#undef VIR_IOTHREAD_SET_PROP_UINT
> +
> if (iothreadInfo->set_thread_pool_min &&
> iothreadInfo->set_thread_pool_max) {
> int curr_max = -1;
> diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
> index 439d4b1916..5a770a800f 100644
> --- a/src/qemu/qemu_validate.c
> +++ b/src/qemu/qemu_validate.c
> @@ -500,9 +500,15 @@ qemuValidateDomainDefIOThreads(const virDomainDef *def,
> for (i = 0; i < def->niothreadids; i++) {
> virDomainIOThreadIDDef *iothread = def->iothreadids[i];
>
> - if (iothread->thread_pool_min != -1 || iothread->thread_pool_max != -1) {
> + if (iothread->thread_pool_min != -1 || iothread->thread_pool_max != -1)
> needsThreadPoolCap = true;
> - break;
> +
> + /* poll-weight requires QEMU_CAPS_IOTHREAD_POLL_WEIGHT */
> + if (iothread->set_poll_weight &&
> + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_IOTHREAD_POLL_WEIGHT)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("poll-weight is not supported by this QEMU binary"));
> + return -1;
> }
> }
>
[...]
> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
> index df0b257cbe..682aaad74f 100644
> --- a/tests/qemuxmlconftest.c
> +++ b/tests/qemuxmlconftest.c
> @@ -2333,6 +2333,8 @@ mymain(void)
> DO_TEST_CAPS_LATEST("iothreads-ids");
> DO_TEST_CAPS_LATEST("iothreads-ids-partial");
> DO_TEST_CAPS_LATEST("iothreads-ids-pool-sizes");
> + DO_TEST_CAPS_LATEST("iothreads-ids-poll-weight");
> + DO_TEST_CAPS_VER_PARSE_ERROR("iothreads-ids-poll-weight", "11.0.0");
I'd not bother with the negative case that just depends on capability.
A more interesting (but not strictly required) one would be with out of
range value.
On 7/29/2026 9:20 AM, Peter Krempa wrote:
> On Wed, Jul 22, 2026 at 13:52:12 -0500, Jaehoon Kim wrote:
>> Use the configured iothread poll-weight value when interacting with
>> QEMU.
>>
>> This wires the new setting into command line generation, monitor data
>> parsing, driver-side parameter handling, and capability-based
>> validation. Remove the break from the iothread validation loop because
>> the loop now also checks poll-weight on every iothread.
>>
>> Signed-off-by: Jaehoon Kim <jhkim@linux.ibm.com>
>> ---
>> include/libvirt/libvirt-domain.h | 26 +++++++++
>> src/qemu/qemu_command.c | 18 +++++-
>> src/qemu/qemu_driver.c | 38 ++++++++++++
>> src/qemu/qemu_monitor.h | 2 +
>> src/qemu/qemu_monitor_json.c | 18 ++++++
>> src/qemu/qemu_validate.c | 10 +++-
>> ...othreads-ids-poll-weight.x86_64-11.0.0.err | 1 +
>> ...threads-ids-poll-weight.x86_64-latest.args | 40 +++++++++++++
>> ...othreads-ids-poll-weight.x86_64-latest.xml | 58 +++++++++++++++++++
>> .../iothreads-ids-poll-weight.xml | 58 +++++++++++++++++++
>> tests/qemuxmlconftest.c | 2 +
>> 11 files changed, 267 insertions(+), 4 deletions(-)
>> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-11.0.0.err
>> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.args
>> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.x86_64-latest.xml
>> create mode 100644 tests/qemuxmlconfdata/iothreads-ids-poll-weight.xml
>>
>> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
>> index 5b67f8f897..f49aa1c136 100644
>> --- a/include/libvirt/libvirt-domain.h
>> +++ b/include/libvirt/libvirt-domain.h
>> @@ -2748,6 +2748,22 @@ int virDomainDelIOThread(virDomainPtr domain,
>> */
>> # define VIR_DOMAIN_IOTHREAD_POLL_SHRINK "poll_shrink"
>>
>> +/**
>> + * VIR_DOMAIN_IOTHREAD_POLL_WEIGHT:
>> + *
>> + * This provides a shift value for the adaptive polling algorithm to control
>> + * how much the most recent event interval affects the next polling duration
>> + * calculation. Larger values decrease the weight of the current interval,
>> + * enabling more gradual adjustments. Valid range is [0, 63]. A value of 0
>> + * lets the hypervisor select a default weight (typically 3, meaning the
> Okay, so 0 is a special value. The parser doesn't treat it as a special
> value. With this impl it would mean that there are 2 manifestation of
> the same "hypervisor default" setting. One is if the 'weight' attribute
> is missing completely. Second one is if it's explicitly set to '0'.
>
> I'm not a fan of having 2 manifestations of the default but I don't have
> a better sugestion either.
>
>> + * current interval contributes approximately 1/8 to the weighted average).
>> + *
>> + * Accepted type is VIR_TYPED_PARAM_UINT.
>> + *
>> + * Since: 12.6.0
> This will have to be 12.7.0, the tree is in freeze for the 12.6.0
> release already.
I will fix to 12.7.0 in v2.
>> + */
>> +# define VIR_DOMAIN_IOTHREAD_POLL_WEIGHT "poll_weight"
>> +
>> /**
>> * VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN:
>> *
>> @@ -4330,6 +4346,16 @@ struct _virDomainStatsRecord {
>> */
>> # define VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_SHRINK ".poll-shrink"
>>
>> +/**
>> + * VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_WEIGHT:
>> + *
>> + * Polling weight factor as an unsigned int. This shift value controls how
>> + * much the most recent event interval affects adaptive polling calculations.
>> + * A 0 (zero) indicates the hypervisor's default weight is used.
>> + *
>> + * Since: 12.6.0
> ditto
>
> So here I presume the presence of this field will be based on whether
> qemu supports this feature (since the stats will be filled from the
> return from qemu) so 0 in fact can be shown even without config. That
> does make sense for the getter.
>
>> + */
>> +# define VIR_DOMAIN_STATS_IOTHREAD_SUFFIX_POLL_WEIGHT ".poll-weight"
>>
>> /**
>> * VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_COUNT:
>> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>> index 95e2ea9a6b..b351059fc1 100644
>> --- a/src/qemu/qemu_command.c
>> +++ b/src/qemu/qemu_command.c
>> @@ -7659,7 +7659,8 @@ qemuBuildMemCommandLine(virCommand *cmd,
>>
>> static int
>> qemuBuildIOThreadCommandLine(virCommand *cmd,
>> - const virDomainDef *def)
>> + const virDomainDef *def,
>> + virQEMUCaps *qemuCaps)
>> {
>> size_t i;
>>
>> @@ -7694,6 +7695,19 @@ qemuBuildIOThreadCommandLine(virCommand *cmd,
>> NULL) < 0)
>> return -1;
>>
>> + if (iothread->set_poll_weight) {
>> + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_IOTHREAD_POLL_WEIGHT)) {
>> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
>> + _("poll-weight is not supported by this QEMU binary"));
>> + return -1;
>> + }
> This check is dead code since qemuValidateDomainDefIOThreads is called
> before this happens in all cases.
>
Agreed. This check is redundant since qemuValidateDomainDefIOThreads
already handles this case before command line generation.
I'll remove it in v2.
>> +
>> + if (virJSONValueObjectAdd(&props,
>> + "u:poll-weight", iothread->poll_weight,
>> + NULL) < 0)
>> + return -1;
>> + }
>> +
>> if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
>> return -1;
>> }
> [...]
>
>
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index bdc0cff66a..1afd6e83ba 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -5261,6 +5261,11 @@ qemuDomainHotplugModIOThreadIDDef(virDomainIOThreadIDDef *def,
>> def->set_poll_shrink = true;
>> }
>>
>> + if (mondef.set_poll_weight) {
>> + def->poll_weight = mondef.poll_weight;
>> + def->set_poll_weight = true;
>> + }
>> +
>> if (mondef.set_thread_pool_min)
>> def->thread_pool_min = mondef.thread_pool_min;
>>
>> @@ -5353,6 +5358,11 @@ qemuDomainHotplugDelIOThread(virDomainObj *vm,
>> * necessary. If a 0 (zero) value is provided, QEMU resets the polling
>> * interval to 0 (zero) allowing the poll-grow to manipulate the time.
>> *
>> + * - "poll-weight" - weight shift value used by the adaptive polling algorithm
>> + * to determine how much the most recent event interval influences the
>> + * next interval calculation. Accepted range is [0, 63]. If a 0 (zero)
>> + * value is provided, QEMU uses its default weight.
>> + *
>> * QEMU keeps track of the polling time elapsed and may grow or shrink the
>> * its polling interval based upon its heuristic algorithm. It is possible
>> * that calculations determine that it has found a "sweet spot" and no
>> @@ -5388,6 +5398,20 @@ qemuDomainIOThreadParseParams(virTypedParameterPtr params,
>> if (rc == 1)
>> iothread->set_poll_shrink = true;
>>
>> + if ((rc = virTypedParamsGetUInt(params, nparams,
>> + VIR_DOMAIN_IOTHREAD_POLL_WEIGHT,
>> + &iothread->poll_weight)) < 0)
>> + return -1;
>> + if (rc == 1) {
>> + if (iothread->poll_weight > 63) {
>> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>> + _("poll-weight value %1$u is out of range [0, 63]"),
>> + iothread->poll_weight);
>> + return -1;
>> + }
>> + iothread->set_poll_weight = true;
>> + }
>> +
>> if ((rc = virTypedParamsGetInt(params, nparams,
>> VIR_DOMAIN_IOTHREAD_THREAD_POOL_MIN,
>> &iothread->thread_pool_min)) < 0)
> [...]
>
>> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
>> index c2afb580e4..e73be4e263 100644
>> --- a/src/qemu/qemu_monitor.h
>> +++ b/src/qemu/qemu_monitor.h
>> @@ -1583,11 +1583,13 @@ struct _qemuMonitorIOThreadInfo {
>> unsigned long long poll_max_ns;
>> unsigned long long poll_grow;
>> unsigned long long poll_shrink;
>> + unsigned int poll_weight;
>> int thread_pool_min;
>> int thread_pool_max;
>> bool set_poll_max_ns;
>> bool set_poll_grow;
>> bool set_poll_shrink;
>> + bool set_poll_weight;
>> bool set_thread_pool_min;
>> bool set_thread_pool_max;
>> };
>> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
>> index 21f4d613b7..c88f74c10b 100644
>> --- a/src/qemu/qemu_monitor_json.c
>> +++ b/src/qemu/qemu_monitor_json.c
>> @@ -7202,6 +7202,11 @@ qemuMonitorJSONGetIOThreads(qemuMonitor *mon,
>> virJSONValueObjectGetNumberUlong(child, "poll-shrink",
>> &info->poll_shrink) == 0)
>> info->poll_valid = true;
>> +
>> + /* poll-weight is optional, only present on newer QEMU */
>> + if (virJSONValueObjectGetNumberUint(child, "poll-weight",
>> + &info->poll_weight) == 0)
>> + info->set_poll_weight = true;
>> }
>>
>> *niothreads = n;
> I'd prefer if this getter code changes are separated. The monitor can
> fetch the values and not use them. Maybe even the stats entries can be
> added before this is set.
I'll split in v2. The monitor getter parsing and the stats reporting will
be move into a separate patch ahead of the setter wiring.
>
>> @@ -7243,6 +7248,19 @@ qemuMonitorJSONSetIOThread(qemuMonitor *mon,
>>
>> #undef VIR_IOTHREAD_SET_PROP_UL
>>
>> +#define VIR_IOTHREAD_SET_PROP_UINT(propName, propVal) \
>> + if (iothreadInfo->set_##propVal) { \
>> + memset(&prop, 0, sizeof(prop)); \
>> + prop.type = QEMU_MONITOR_OBJECT_PROPERTY_UINT; \
>> + prop.val.ui = iothreadInfo->propVal; \
>> + if (qemuMonitorJSONSetObjectProperty(mon, path, propName, &prop) < 0) \
>> + return -1; \
>> + }
>> +
>> + VIR_IOTHREAD_SET_PROP_UINT("poll-weight", poll_weight);
>> +
>> +#undef VIR_IOTHREAD_SET_PROP_UINT
>> +
>> if (iothreadInfo->set_thread_pool_min &&
>> iothreadInfo->set_thread_pool_max) {
>> int curr_max = -1;
>> diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
>> index 439d4b1916..5a770a800f 100644
>> --- a/src/qemu/qemu_validate.c
>> +++ b/src/qemu/qemu_validate.c
>> @@ -500,9 +500,15 @@ qemuValidateDomainDefIOThreads(const virDomainDef *def,
>> for (i = 0; i < def->niothreadids; i++) {
>> virDomainIOThreadIDDef *iothread = def->iothreadids[i];
>>
>> - if (iothread->thread_pool_min != -1 || iothread->thread_pool_max != -1) {
>> + if (iothread->thread_pool_min != -1 || iothread->thread_pool_max != -1)
>> needsThreadPoolCap = true;
>> - break;
>> +
>> + /* poll-weight requires QEMU_CAPS_IOTHREAD_POLL_WEIGHT */
>> + if (iothread->set_poll_weight &&
>> + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_IOTHREAD_POLL_WEIGHT)) {
>> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
>> + _("poll-weight is not supported by this QEMU binary"));
>> + return -1;
>> }
>> }
>>
> [...]
>
>> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
>> index df0b257cbe..682aaad74f 100644
>> --- a/tests/qemuxmlconftest.c
>> +++ b/tests/qemuxmlconftest.c
>> @@ -2333,6 +2333,8 @@ mymain(void)
>> DO_TEST_CAPS_LATEST("iothreads-ids");
>> DO_TEST_CAPS_LATEST("iothreads-ids-partial");
>> DO_TEST_CAPS_LATEST("iothreads-ids-pool-sizes");
>> + DO_TEST_CAPS_LATEST("iothreads-ids-poll-weight");
>> + DO_TEST_CAPS_VER_PARSE_ERROR("iothreads-ids-poll-weight", "11.0.0");
> I'd not bother with the negative case that just depends on capability.
>
> A more interesting (but not strictly required) one would be with out of
> range value.
I will drop the capability based negative test in v2.
Thanks,
Jaehoon
© 2016 - 2026 Red Hat, Inc.