IORING_SETUP_SINGLE_ISSUER enables optimizations in the host Linux kernel's io_uring code when the io_uring context is only used from a single thread. This is true is QEMU because io_uring SQEs are submitted from the same thread that processes the CQEs.
Signed-off-by: Stefan Hajnoczi <[email protected]> --- util/fdmon-io_uring.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c index d0b56127c6..ec056b4818 100644 --- a/util/fdmon-io_uring.c +++ b/util/fdmon-io_uring.c @@ -452,13 +452,31 @@ static const FDMonOps fdmon_io_uring_ops = { .add_sqe = fdmon_io_uring_add_sqe, }; +static inline bool is_creating_iothread(void) +{ + return qemu_get_thread_id() != getpid(); +} + bool fdmon_io_uring_setup(AioContext *ctx, Error **errp) { + unsigned flags = 0; int ret; + /* + * The main thread's AioContexts are created from the main loop thread but + * may be accessed from multiple threads (e.g. vCPUs or the migration + * thread). IOThread AioContexts are only accessed from the IOThread + * itself. + */ +#if IORING_SETUP_SINGLE_ISSUER + if (is_creating_iothread()) { + flags |= IORING_SETUP_SINGLE_ISSUER; + } +#endif + ctx->io_uring_fd_tag = NULL; - ret = io_uring_queue_init(FDMON_IO_URING_ENTRIES, &ctx->fdmon_io_uring, 0); + ret = io_uring_queue_init(FDMON_IO_URING_ENTRIES, &ctx->fdmon_io_uring, flags); if (ret != 0) { error_setg_errno(errp, -ret, "Failed to initialize io_uring"); return false; -- 2.53.0
