Cc: [email protected] for a possible query-iothreads change discussed below.
JAEHOON KIM <[email protected]> writes: > On 1/14/2026 1:48 AM, Markus Armbruster wrote: >> Jaehoon Kim <[email protected]> writes: >> >>> Introduce a new poll-weight parameter for aio-poll. This parameter >>> controls how much the most recent event interval affects the next >>> polling duration. When set to 0, a default value of 2 is used, meaning >>> the current interval contributes roughly 25% to the calculation. Larger >>> values decrease the weight of the current interval, enabling more >>> gradual adjustments to polling duration. >>> >>> Signed-off-by: Jaehoon Kim <[email protected]> >> [...] >> >>> diff --git a/qapi/misc.json b/qapi/misc.json >>> index 28c641fe2f..b21cc48a03 100644 >>> --- a/qapi/misc.json >>> +++ b/qapi/misc.json >>> @@ -85,6 +85,11 @@ >>> # @poll-shrink: how many ns will be removed from polling time, 0 means >>> # that it's not configured (since 2.9) >>> # >>> +# @poll-weight: the weight factor for adaptive polling. >>> +# Determines how much the current event interval contributes to >>> +# the next polling time calculation. 0 means that the default >>> +# value is used. (since 10.1) >> >> When the default value is used, the actual value being used remains >> hidden. Why? > > Actually, I just followed the existing pattern of poll-grow, which also > defaults to a factor of 2 when set to 0. Yes, and consistency is always desirable. But let's have a look at the new interface in isolation, to see whether it's actually good. > It wasn't my intention to hide the value; I kept this because the > previous API has been working fine without issues. > If you think the actual value should be visible, I'll consider ways to > make it explicit in the next version. As is, query-iothreads tells us "the weight factor for adaptive polling is X, and it was set by the user", or "the weight factor for adaptive polling was not set by the user, but picked by the system." If we returned the actual value, it would tell us "the weight factor for adaptive polling is X". Only the former interface tells us whether the user or the system picked. Only the latter interface tells us what the system picked. Which one is useful in practice? I'd argue the latter. A management application knows whether it set a value without query-iothreads' help, but it doesn't know what the system picked. The people coding it may know if a contract specifies what the system picks (see below). If we conclude that returning the actual value is better for new @poll-weight, then it would surely be better for @poll-grow and @poll-shrink, too. Could we still improve them? Libvirt developers, any advice? >>> +# >>> # @aio-max-batch: maximum number of requests in a batch for the AIO >>> # engine, 0 means that the engine will use its default (since 6.1) >>> # >>> @@ -96,6 +101,7 @@ >>> 'poll-max-ns': 'int', >>> 'poll-grow': 'int', >>> 'poll-shrink': 'int', >>> + 'poll-weight': 'int', >>> 'aio-max-batch': 'int' } } >>> >>> ## >>> diff --git a/qapi/qom.json b/qapi/qom.json >>> index 6f5c9de0f0..d90823478d 100644 >>> --- a/qapi/qom.json >>> +++ b/qapi/qom.json >>> @@ -606,6 +606,11 @@ >>> # algorithm detects it is spending too long polling without >>> # encountering events. 0 selects a default behaviour (default: 0) >>> # >>> +# @poll-weight: the weight factor for adaptive polling. >>> +# Determines how much the current event interval contributes to >>> +# the next polling time calculation. 0 selects a default >>> +# behaviour (default: 0) since 10.1. >> >> This leaves the actual default behavior unspecified. Is this a good >> idea? > > I agree that the documentation should be more explicit. > I'll update it to clarify that the default factor is 2 and explain its > meaning. I understand that you're mirroring how @poll-grow and @poll-shrink work, but let's ignore that for a minute. Compare four possible interfaces: 1. Optional @poll-weight defaults to 2. Values <= 0 are rejected. 2. Optional @poll-weight defaults to 2. Value 0 is replaced by the default value 2. Values < 0 are rejected. 3. Optional @poll-weight defaults to 0. Values < 0 are rejected. Value 0 makes the system pick a value, namely 2. 4. Optional @poll-weight defaults to 0. Values < 0 are rejected. Value 0 makes the system pick a value. It currently picks 2. The difference between 3. and 4. is that 3. makes "system picks 2" part of the contract, while 4. doesn't. 1. is the simplest. Is 2.'s additional complexity worthwhile? 3.'s? 4.'s? >>> +# >>> # The @aio-max-batch option is available since 6.1. >>> # >>> # Since: 2.0 >>> @@ -614,7 +619,8 @@ >>> 'base': 'EventLoopBaseProperties', >>> 'data': { '*poll-max-ns': 'int', >>> '*poll-grow': 'int', >>> - '*poll-shrink': 'int' } } >>> + '*poll-shrink': 'int', >>> + '*poll-weight': 'int' } } >>> >>> ## >>> # @MainLoopProperties: >> >> [...]
