Skip to content

Commit 1793ad0

Browse files
stefano-garzarellastefanhaRH
authored andcommitted
iothread: add aio-max-batch parameter
The `aio-max-batch` parameter will be propagated to AIO engines and it will be used to control the maximum number of queued requests. When there are in queue a number of requests equal to `aio-max-batch`, the engine invokes the system call to forward the requests to the kernel. This parameter allows us to control the maximum batch size to reduce the latency that requests might accumulate while queued in the AIO engine queue. If `aio-max-batch` is equal to 0 (default value), the AIO engine will use its default maximum batch size value. Signed-off-by: Stefano Garzarella <[email protected]> Message-id: [email protected] Signed-off-by: Stefan Hajnoczi <[email protected]>
1 parent 0445409 commit 1793ad0

File tree

10 files changed

+103
-9
lines changed

10 files changed

+103
-9
lines changed

include/block/aio.h

+12
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ struct AioContext {
232232
int64_t poll_grow; /* polling time growth factor */
233233
int64_t poll_shrink; /* polling time shrink factor */
234234

235+
/* AIO engine parameters */
236+
int64_t aio_max_batch; /* maximum number of requests in a batch */
237+
235238
/*
236239
* List of handlers participating in userspace polling. Protected by
237240
* ctx->list_lock. Iterated and modified mostly by the event loop thread
@@ -755,4 +758,13 @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
755758
int64_t grow, int64_t shrink,
756759
Error **errp);
757760

761+
/**
762+
* aio_context_set_aio_params:
763+
* @ctx: the aio context
764+
* @max_batch: maximum number of requests in a batch, 0 means that the
765+
* engine will use its default
766+
*/
767+
void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
768+
Error **errp);
769+
758770
#endif

include/sysemu/iothread.h

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ struct IOThread {
3737
int64_t poll_max_ns;
3838
int64_t poll_grow;
3939
int64_t poll_shrink;
40+
41+
/* AioContext AIO engine parameters */
42+
int64_t aio_max_batch;
4043
};
4144
typedef struct IOThread IOThread;
4245

iothread.c

+50-5
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,24 @@ static void iothread_init_gcontext(IOThread *iothread)
152152
iothread->main_loop = g_main_loop_new(iothread->worker_context, TRUE);
153153
}
154154

155+
static void iothread_set_aio_context_params(IOThread *iothread, Error **errp)
156+
{
157+
ERRP_GUARD();
158+
159+
aio_context_set_poll_params(iothread->ctx,
160+
iothread->poll_max_ns,
161+
iothread->poll_grow,
162+
iothread->poll_shrink,
163+
errp);
164+
if (*errp) {
165+
return;
166+
}
167+
168+
aio_context_set_aio_params(iothread->ctx,
169+
iothread->aio_max_batch,
170+
errp);
171+
}
172+
155173
static void iothread_complete(UserCreatable *obj, Error **errp)
156174
{
157175
Error *local_error = NULL;
@@ -171,11 +189,7 @@ static void iothread_complete(UserCreatable *obj, Error **errp)
171189
*/
172190
iothread_init_gcontext(iothread);
173191

174-
aio_context_set_poll_params(iothread->ctx,
175-
iothread->poll_max_ns,
176-
iothread->poll_grow,
177-
iothread->poll_shrink,
178-
&local_error);
192+
iothread_set_aio_context_params(iothread, &local_error);
179193
if (local_error) {
180194
error_propagate(errp, local_error);
181195
aio_context_unref(iothread->ctx);
@@ -212,6 +226,9 @@ static PollParamInfo poll_grow_info = {
212226
static PollParamInfo poll_shrink_info = {
213227
"poll-shrink", offsetof(IOThread, poll_shrink),
214228
};
229+
static PollParamInfo aio_max_batch_info = {
230+
"aio-max-batch", offsetof(IOThread, aio_max_batch),
231+
};
215232

216233
static void iothread_get_param(Object *obj, Visitor *v,
217234
const char *name, void *opaque, Error **errp)
@@ -271,6 +288,29 @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
271288
}
272289
}
273290

291+
static void iothread_get_aio_param(Object *obj, Visitor *v,
292+
const char *name, void *opaque, Error **errp)
293+
{
294+
295+
iothread_get_param(obj, v, name, opaque, errp);
296+
}
297+
298+
static void iothread_set_aio_param(Object *obj, Visitor *v,
299+
const char *name, void *opaque, Error **errp)
300+
{
301+
IOThread *iothread = IOTHREAD(obj);
302+
303+
if (!iothread_set_param(obj, v, name, opaque, errp)) {
304+
return;
305+
}
306+
307+
if (iothread->ctx) {
308+
aio_context_set_aio_params(iothread->ctx,
309+
iothread->aio_max_batch,
310+
errp);
311+
}
312+
}
313+
274314
static void iothread_class_init(ObjectClass *klass, void *class_data)
275315
{
276316
UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
@@ -288,6 +328,10 @@ static void iothread_class_init(ObjectClass *klass, void *class_data)
288328
iothread_get_poll_param,
289329
iothread_set_poll_param,
290330
NULL, &poll_shrink_info);
331+
object_class_property_add(klass, "aio-max-batch", "int",
332+
iothread_get_aio_param,
333+
iothread_set_aio_param,
334+
NULL, &aio_max_batch_info);
291335
}
292336

293337
static const TypeInfo iothread_info = {
@@ -337,6 +381,7 @@ static int query_one_iothread(Object *object, void *opaque)
337381
info->poll_max_ns = iothread->poll_max_ns;
338382
info->poll_grow = iothread->poll_grow;
339383
info->poll_shrink = iothread->poll_shrink;
384+
info->aio_max_batch = iothread->aio_max_batch;
340385

341386
QAPI_LIST_APPEND(*tail, info);
342387
return 0;

monitor/hmp-cmds.c

+2
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,8 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
18931893
monitor_printf(mon, " poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
18941894
monitor_printf(mon, " poll-grow=%" PRId64 "\n", value->poll_grow);
18951895
monitor_printf(mon, " poll-shrink=%" PRId64 "\n", value->poll_shrink);
1896+
monitor_printf(mon, " aio-max-batch=%" PRId64 "\n",
1897+
value->aio_max_batch);
18961898
}
18971899

18981900
qapi_free_IOThreadInfoList(info_list);

qapi/misc.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,18 @@
8686
# @poll-shrink: how many ns will be removed from polling time, 0 means that
8787
# it's not configured (since 2.9)
8888
#
89+
# @aio-max-batch: maximum number of requests in a batch for the AIO engine,
90+
# 0 means that the engine will use its default (since 6.1)
91+
#
8992
# Since: 2.0
9093
##
9194
{ 'struct': 'IOThreadInfo',
9295
'data': {'id': 'str',
9396
'thread-id': 'int',
9497
'poll-max-ns': 'int',
9598
'poll-grow': 'int',
96-
'poll-shrink': 'int' } }
99+
'poll-shrink': 'int',
100+
'aio-max-batch': 'int' } }
97101

98102
##
99103
# @query-iothreads:

qapi/qom.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,17 @@
516516
# algorithm detects it is spending too long polling without
517517
# encountering events. 0 selects a default behaviour (default: 0)
518518
#
519+
# @aio-max-batch: maximum number of requests in a batch for the AIO engine,
520+
# 0 means that the engine will use its default
521+
# (default:0, since 6.1)
522+
#
519523
# Since: 2.0
520524
##
521525
{ 'struct': 'IothreadProperties',
522526
'data': { '*poll-max-ns': 'int',
523527
'*poll-grow': 'int',
524-
'*poll-shrink': 'int' } }
528+
'*poll-shrink': 'int',
529+
'*aio-max-batch': 'int' } }
525530

526531
##
527532
# @MemoryBackendProperties:

qemu-options.hx

+6-2
Original file line numberDiff line numberDiff line change
@@ -5301,7 +5301,7 @@ SRST
53015301

53025302
CN=laptop.example.com,O=Example Home,L=London,ST=London,C=GB
53035303

5304-
``-object iothread,id=id,poll-max-ns=poll-max-ns,poll-grow=poll-grow,poll-shrink=poll-shrink``
5304+
``-object iothread,id=id,poll-max-ns=poll-max-ns,poll-grow=poll-grow,poll-shrink=poll-shrink,aio-max-batch=aio-max-batch``
53055305
Creates a dedicated event loop thread that devices can be
53065306
assigned to. This is known as an IOThread. By default device
53075307
emulation happens in vCPU threads or the main event loop thread.
@@ -5337,7 +5337,11 @@ SRST
53375337
the polling time when the algorithm detects it is spending too
53385338
long polling without encountering events.
53395339

5340-
The polling parameters can be modified at run-time using the
5340+
The ``aio-max-batch`` parameter is the maximum number of requests
5341+
in a batch for the AIO engine, 0 means that the engine will use
5342+
its default.
5343+
5344+
The IOThread parameters can be modified at run-time using the
53415345
``qom-set`` command (where ``iothread1`` is the IOThread's
53425346
``id``):
53435347

util/aio-posix.c

+12
Original file line numberDiff line numberDiff line change
@@ -716,3 +716,15 @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
716716

717717
aio_notify(ctx);
718718
}
719+
720+
void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
721+
Error **errp)
722+
{
723+
/*
724+
* No thread synchronization here, it doesn't matter if an incorrect value
725+
* is used once.
726+
*/
727+
ctx->aio_max_batch = max_batch;
728+
729+
aio_notify(ctx);
730+
}

util/aio-win32.c

+5
Original file line numberDiff line numberDiff line change
@@ -440,3 +440,8 @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
440440
error_setg(errp, "AioContext polling is not implemented on Windows");
441441
}
442442
}
443+
444+
void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
445+
Error **errp)
446+
{
447+
}

util/async.c

+2
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,8 @@ AioContext *aio_context_new(Error **errp)
554554
ctx->poll_grow = 0;
555555
ctx->poll_shrink = 0;
556556

557+
ctx->aio_max_batch = 0;
558+
557559
return ctx;
558560
fail:
559561
g_source_destroy(&ctx->source);

0 commit comments

Comments
 (0)