On Wed, Jul 22, 2026 at 13:52:13 -0500, Jaehoon Kim wrote:
> Add virsh support for configuring and reporting iothread poll-weight.
>
> Document poll-weight in the virsh manpage and extend iothreadset so
> that poll-weight can be configured from the command line. Also add
> poll-weight support to the test driver and extend virshtest accordingly.
>
> Signed-off-by: Jaehoon Kim <[email protected]>
> ---
> docs/manpages/virsh.rst | 18 ++++++++++++------
> src/test/test_driver.c | 12 ++++++++++++
> tests/virshtestdata/iothreads.in | 2 ++
> tests/virshtestdata/iothreads.out | 18 ++++++++++++++++++
> tools/virsh-domain.c | 18 ++++++++++++++++++
> 5 files changed, 62 insertions(+), 6 deletions(-)
>
> diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
> index a10d29e0ea..24052d0cdb 100644
> --- a/docs/manpages/virsh.rst
> +++ b/docs/manpages/virsh.rst
> @@ -2905,6 +2905,8 @@ not available for statistical purposes.
> growth is managed by the hypervisor.
> * ``iothread.<id>.poll-shrink`` - polling time shrink value. A value of
> (zero) indicates shrink is managed by hypervisor.
> +* ``iothread.<id>.poll-weight`` - polling weight shift value. A value of 0
> + (zero) indicates the hypervisor's default weight is used.
This hunk belongs to the patch that adds the stats gathering code since
it starts being emitted at that point.
This patch is adding the code to modify the setting.
>
> *--memory* returns:
>
> @@ -3498,8 +3500,8 @@ iothreadset
> ::
>
> iothreadset domain iothread_id [[--poll-max-ns ns] [--poll-grow factor]
> - [--poll-shrink divisor] [--thread-pool-min value]
> - [--thread-pool-max value]]
> + [--poll-shrink divisor] [--poll-weight factor]
> + [--thread-pool-min value] [--thread-pool-max value]]
> [[--config] [--live] | [--current]]
>
> Modifies an existing iothread of the domain using the specified
> @@ -3511,10 +3513,14 @@ reach the maximum polling time. If a 0 (zero) is
> provided, then the
> default factor will be used. The *--poll-shrink* is the quotient
> by which the current polling time will be reduced in order to get
> below the maximum polling interval. If a 0 (zero) is provided, then
> -the default quotient will be used. The polling values are purely dynamic
> -for a running guest. Saving, destroying, stopping, etc. the guest will
> -result in the polling values returning to hypervisor defaults at the
> -next start, restore, etc.
> +the default quotient will be used. The *--poll-weight* sets the weight
> +shift value for adaptive polling, determining how much the most recent
> +event interval affects the next polling duration calculation. Larger
> +values reduce the weight of recent events. Valid range is [0, 63].
> +If omitted or set to 0, the hypervisor selects a default.
This is not accurate. If the --poll-weight parameter is not supplied
this virsh command will not put the VIR_DOMAIN_IOTHREAD_POLL_WEIGHT
parameter to the list of stuff to change.
At that point the backend code will not modify this value rather than
set it to the default.
> +The polling values are purely dynamic for a running guest. Saving,
> +destroying, stopping, etc. the guest will result in the polling values
> +returning to hypervisor defaults at the next start, restore, etc.
>
> The *--thread-pool-min* and *--thread-pool-max* options then set lower and
> upper bound, respectively of number of threads in worker pool of given
> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> index 536e291861..8546c3e251 100644
> --- a/src/test/test_driver.c
> +++ b/src/test/test_driver.c
> @@ -189,6 +189,7 @@ struct _testIOThreadInfo {
> unsigned long long poll_max_ns;
> unsigned int poll_grow;
> unsigned int poll_shrink;
> + unsigned int poll_weight;
> };
>
> static void
> @@ -749,6 +750,7 @@ testDomainGenerateIOThreadInfos(virDomainObj *obj)
> iothread.poll_max_ns = 32768;
> iothread.poll_grow = 0;
> iothread.poll_shrink = 0;
> + iothread.poll_weight = 0;
> g_array_append_val(priv->iothreads, iothread);
> }
> }
> @@ -9681,6 +9683,7 @@ testDomainAddIOThread(virDomainPtr dom,
> iothread.poll_max_ns = 32768;
> iothread.poll_grow = 0;
> iothread.poll_shrink = 0;
> + iothread.poll_weight = 0;
>
> g_array_append_val(priv->iothreads, iothread);
>
> @@ -9795,6 +9798,8 @@ testDomainIOThreadParseParams(virTypedParameterPtr
> params,
> VIR_TYPED_PARAM_UINT,
> VIR_DOMAIN_IOTHREAD_POLL_SHRINK,
> VIR_TYPED_PARAM_UINT,
> + VIR_DOMAIN_IOTHREAD_POLL_WEIGHT,
> + VIR_TYPED_PARAM_UINT,
> NULL) < 0)
> return -1;
>
> @@ -9813,6 +9818,11 @@ testDomainIOThreadParseParams(virTypedParameterPtr
> params,
> &iothread->poll_shrink) < 0)
> return -1;
>
> + if (virTypedParamsGetUInt(params, nparams,
> + VIR_DOMAIN_IOTHREAD_POLL_WEIGHT,
> + &iothread->poll_weight) < 0)
> + return -1;
> +
> return 0;
> }
>
> @@ -9899,6 +9909,8 @@ testDomainGetStatsIOThread(virDomainObj *dom,
> "iothread.%u.poll-grow",
> iothread.iothread_id);
> virTypedParamListAddUInt(params, iothread.poll_shrink,
> "iothread.%u.poll-shrink",
> iothread.iothread_id);
> + virTypedParamListAddUInt(params, iothread.poll_weight,
> + "iothread.%u.poll-weight",
> iothread.iothread_id);
> }
>
> return 0;
Please separate the testr driver changes into a separate patch.
> diff --git a/tests/virshtestdata/iothreads.in
> b/tests/virshtestdata/iothreads.in
> index 25ebcb5cda..b5aed83bba 100644
> --- a/tests/virshtestdata/iothreads.in
> +++ b/tests/virshtestdata/iothreads.in
> @@ -7,6 +7,8 @@ iothreadinfo --domain fc4
> domstats --domain fc4
> iothreadset --domain fc4 --id 6 --poll-max-ns 100 --poll-shrink 10
> --poll-grow 10
> domstats --domain fc4
> +iothreadset --domain fc4 --id 6 --poll-weight 3
> +domstats --domain fc4
>
> iothreadadd --domain fc5 --id 2
> iothreadinfo --domain fc5
> diff --git a/tests/virshtestdata/iothreads.out
> b/tests/virshtestdata/iothreads.out
> index 1e38733bcf..a51593d765 100644
> --- a/tests/virshtestdata/iothreads.out
> +++ b/tests/virshtestdata/iothreads.out
> @@ -23,9 +23,11 @@ Domain: 'fc4'
> iothread.4.poll-max-ns=32768
> iothread.4.poll-grow=0
> iothread.4.poll-shrink=0
> + iothread.4.poll-weight=0
> iothread.6.poll-max-ns=32768
> iothread.6.poll-grow=0
> iothread.6.poll-shrink=0
> + iothread.6.poll-weight=0
>
>
> Domain: 'fc4'
> @@ -35,9 +37,25 @@ Domain: 'fc4'
> iothread.4.poll-max-ns=32768
> iothread.4.poll-grow=0
> iothread.4.poll-shrink=0
> + iothread.4.poll-weight=0
> iothread.6.poll-max-ns=100
> iothread.6.poll-grow=10
> iothread.6.poll-shrink=10
> + iothread.6.poll-weight=0
> +
> +
> +Domain: 'fc4'
> + state.state=1
> + state.reason=0
> + iothread.count=2
> + iothread.4.poll-max-ns=32768
> + iothread.4.poll-grow=0
> + iothread.4.poll-shrink=0
> + iothread.4.poll-weight=0
> + iothread.6.poll-max-ns=100
> + iothread.6.poll-grow=10
> + iothread.6.poll-shrink=10
> + iothread.6.poll-weight=3
>
>
> IOThread ID CPU Affinity
IIUC the fetching of the value will change this output right when the
test driver code is changed, so those bits will need to be moved there.
The last one where the weight is set will need to happen after that
patch but also possibly in a separate commit.
> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
> index aa4f2a7a48..2e4923283b 100644
> --- a/tools/virsh-domain.c
> +++ b/tools/virsh-domain.c
> @@ -8270,6 +8270,11 @@ static const vshCmdOptDef opts_iothreadset[] = {
> .unwanted_positional = true,
> .help = N_("set the value for reduction of the IOThread polling time")
> },
> + {.name = "poll-weight",
> + .type = VSH_OT_INT,
> + .unwanted_positional = true,
> + .help = N_("set the adaptive polling weight factor")
> + },
> {.name = "thread-pool-min",
> .type = VSH_OT_INT,
> .unwanted_positional = true,
> @@ -8299,6 +8304,7 @@ cmdIOThreadSet(vshControl *ctl, const vshCmd *cmd)
> virTypedParameterPtr par;
> size_t npar = 0;
> unsigned long long poll_val;
> + unsigned int poll_weight;
> int thread_val;
> int rc;
>
> @@ -8335,6 +8341,18 @@ cmdIOThreadSet(vshControl *ctl, const vshCmd *cmd)
> if (rc > 0)
> virTypedParamListAddUnsigned(params, poll_val,
> VIR_DOMAIN_IOTHREAD_POLL_SHRINK);
>
> + if ((rc = vshCommandOptUInt(ctl, cmd, "poll-weight", &poll_weight)) < 0)
> + return false;
> + if (rc > 0) {
> + if (poll_weight > 63) {
> + vshError(ctl, _("poll-weight value %1$u is out of range [0,
> 63]"),
> + poll_weight);
> + return false;
> + }
> +
> + virTypedParamListAddUInt(params, poll_weight,
> VIR_DOMAIN_IOTHREAD_POLL_WEIGHT);
> + }
> +
> if ((rc = vshCommandOptInt(ctl, cmd, "thread-pool-min", &thread_val)) <
> 0)
> return false;
> if (rc > 0)
> --
> 2.54.0
>