summaryrefslogtreecommitdiff
path: root/iothread.c
diff options
context:
space:
mode:
authorJaehoon Kim <jhkim@linux.ibm.com>2026-04-23 14:59:18 -0500
committerStefan Hajnoczi <stefanha@redhat.com>2026-04-29 11:31:44 -0400
commit9fea80ddf0f58fed94f7e6d7d5c9e0ccf5cff44a (patch)
tree77279b8832d5d7e1d1b3143eb45b949ccdbd459d /iothread.c
parent9563d0b5e2d2056373e8af9eeb674fe64c19b2b2 (diff)
downloadqemu-9fea80ddf0f58fed94f7e6d7d5c9e0ccf5cff44a.tar.gz
qemu-9fea80ddf0f58fed94f7e6d7d5c9e0ccf5cff44a.zip
qapi/iothread: introduce poll-weight parameter for aio-poll
Introduce a configurable poll-weight parameter for adaptive polling in IOThread. This parameter replaces the hardcoded POLL_WEIGHT_SHIFT constant, allowing runtime control over how much the most recent event interval affects the next polling duration calculation. The poll-weight parameter uses a shift value where larger values decrease the weight of the current interval, enabling more gradual adjustments. When set to 0, a default value of 3 is used (meaning the current interval contributes approximately 1/8 to the weighted average). This patch also removes the hardcoded default value checks from adjust_polling_time(). Instead, poll-grow, poll-shrink, and poll-weight now use default values initialized in iothread.c during IOThread creation. Signed-off-by: Jaehoon Kim <jhkim@linux.ibm.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Acked-by: Markus Armbruster <armbru@redhat.com> Message-ID: <20260423195918.661299-4-jhkim@linux.ibm.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'iothread.c')
-rw-r--r--iothread.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/iothread.c b/iothread.c
index caf68e0764..3558535b40 100644
--- a/iothread.c
+++ b/iothread.c
@@ -25,17 +25,6 @@
#include "qemu/rcu.h"
#include "qemu/main-loop.h"
-
-#ifdef CONFIG_POSIX
-/* Benchmark results from 2016 on NVMe SSD drives show max polling times around
- * 16-32 microseconds yield IOPS improvements for both iodepth=1 and iodepth=32
- * workloads.
- */
-#define IOTHREAD_POLL_MAX_NS_DEFAULT 32768ULL
-#else
-#define IOTHREAD_POLL_MAX_NS_DEFAULT 0ULL
-#endif
-
static void *iothread_run(void *opaque)
{
IOThread *iothread = opaque;
@@ -103,6 +92,10 @@ static void iothread_instance_init(Object *obj)
IOThread *iothread = IOTHREAD(obj);
iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT;
+ iothread->poll_grow = IOTHREAD_POLL_GROW_DEFAULT;
+ iothread->poll_shrink = IOTHREAD_POLL_SHRINK_DEFAULT;
+ iothread->poll_weight = IOTHREAD_POLL_WEIGHT_DEFAULT;
+
iothread->thread_id = -1;
qemu_sem_init(&iothread->init_done_sem, 0);
/* By default, we don't run gcontext */
@@ -164,6 +157,7 @@ static void iothread_set_aio_context_params(EventLoopBase *base, Error **errp)
iothread->poll_max_ns,
iothread->poll_grow,
iothread->poll_shrink,
+ iothread->poll_weight,
errp);
if (*errp) {
return;
@@ -233,6 +227,9 @@ static IOThreadParamInfo poll_grow_info = {
static IOThreadParamInfo poll_shrink_info = {
"poll-shrink", offsetof(IOThread, poll_shrink),
};
+static IOThreadParamInfo poll_weight_info = {
+ "poll-weight", offsetof(IOThread, poll_weight),
+};
static void iothread_get_param(Object *obj, Visitor *v,
const char *name, IOThreadParamInfo *info, Error **errp)
@@ -254,13 +251,31 @@ static bool iothread_set_param(Object *obj, Visitor *v,
return false;
}
- if (value < 0) {
+ if (info->offset == offsetof(IOThread, poll_weight)) {
+ if (value < 0 || value > 63) {
+ error_setg(errp, "%s value must be in range [0, 63]",
+ info->name);
+ return false;
+ }
+ } else if (value < 0) {
error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
info->name, INT64_MAX);
return false;
}
- *field = value;
+ if (value == 0) {
+ if (info->offset == offsetof(IOThread, poll_grow)) {
+ *field = IOTHREAD_POLL_GROW_DEFAULT;
+ } else if (info->offset == offsetof(IOThread, poll_shrink)) {
+ *field = IOTHREAD_POLL_SHRINK_DEFAULT;
+ } else if (info->offset == offsetof(IOThread, poll_weight)) {
+ *field = IOTHREAD_POLL_WEIGHT_DEFAULT;
+ } else {
+ *field = value;
+ }
+ } else {
+ *field = value;
+ }
return true;
}
@@ -288,6 +303,7 @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
iothread->poll_max_ns,
iothread->poll_grow,
iothread->poll_shrink,
+ iothread->poll_weight,
errp);
}
}
@@ -311,6 +327,10 @@ static void iothread_class_init(ObjectClass *klass, const void *class_data)
iothread_get_poll_param,
iothread_set_poll_param,
NULL, &poll_shrink_info);
+ object_class_property_add(klass, "poll-weight", "int",
+ iothread_get_poll_param,
+ iothread_set_poll_param,
+ NULL, &poll_weight_info);
}
static const TypeInfo iothread_info = {
@@ -356,6 +376,7 @@ static int query_one_iothread(Object *object, void *opaque)
info->poll_max_ns = iothread->poll_max_ns;
info->poll_grow = iothread->poll_grow;
info->poll_shrink = iothread->poll_shrink;
+ info->poll_weight = iothread->poll_weight;
info->aio_max_batch = iothread->parent_obj.aio_max_batch;
QAPI_LIST_APPEND(*tail, info);