diff options
author | Emanuele Giuseppe Esposito <eesposit@redhat.com> | 2023-02-03 08:17:29 -0500 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2023-04-25 13:17:28 +0200 |
commit | a75e4e43659223bac1c94e11569547ec61d98543 (patch) | |
tree | a282535cd2d4c25c0f860f05d436328a978f03e4 | |
parent | ab50533b6946b1adeb8eef62c6b16689abcd1e70 (diff) | |
download | qemu-a75e4e43659223bac1c94e11569547ec61d98543.zip qemu-a75e4e43659223bac1c94e11569547ec61d98543.tar.gz qemu-a75e4e43659223bac1c94e11569547ec61d98543.tar.bz2 |
io_uring: use LuringState from the running thread
Remove usage of aio_context_acquire by always submitting asynchronous
AIO to the current thread's LuringState.
In order to prevent mistakes from the caller side, avoid passing LuringState
in luring_io_{plug/unplug} and luring_co_submit, and document the functions
to make clear that they work in the current thread's AioContext.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Message-Id: <20230203131731.851116-3-eesposit@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | block/file-posix.c | 12 | ||||
-rw-r--r-- | block/io_uring.c | 23 | ||||
-rw-r--r-- | include/block/aio.h | 4 | ||||
-rw-r--r-- | include/block/raw-aio.h | 15 |
4 files changed, 30 insertions, 24 deletions
diff --git a/block/file-posix.c b/block/file-posix.c index 1b43428..30cb4ae 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2089,9 +2089,8 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, type |= QEMU_AIO_MISALIGNED; #ifdef CONFIG_LINUX_IO_URING } else if (s->use_linux_io_uring) { - LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs)); assert(qiov->size == bytes); - return luring_co_submit(bs, aio, s->fd, offset, qiov, type); + return luring_co_submit(bs, s->fd, offset, qiov, type); #endif #ifdef CONFIG_LINUX_AIO } else if (s->use_linux_aio) { @@ -2140,8 +2139,7 @@ static void coroutine_fn raw_co_io_plug(BlockDriverState *bs) #endif #ifdef CONFIG_LINUX_IO_URING if (s->use_linux_io_uring) { - LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs)); - luring_io_plug(bs, aio); + luring_io_plug(); } #endif } @@ -2156,8 +2154,7 @@ static void coroutine_fn raw_co_io_unplug(BlockDriverState *bs) #endif #ifdef CONFIG_LINUX_IO_URING if (s->use_linux_io_uring) { - LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs)); - luring_io_unplug(bs, aio); + luring_io_unplug(); } #endif } @@ -2181,8 +2178,7 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs) #ifdef CONFIG_LINUX_IO_URING if (s->use_linux_io_uring) { - LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs)); - return luring_co_submit(bs, aio, s->fd, 0, NULL, QEMU_AIO_FLUSH); + return luring_co_submit(bs, s->fd, 0, NULL, QEMU_AIO_FLUSH); } #endif return raw_thread_pool_submit(bs, handle_aiocb_flush, &acb); diff --git a/block/io_uring.c b/block/io_uring.c index 973e15d..989f9a9 100644 --- a/block/io_uring.c +++ b/block/io_uring.c @@ -18,6 +18,9 @@ #include "qapi/error.h" #include "trace.h" +/* Only used for assertions. */ +#include "qemu/coroutine_int.h" + /* io_uring ring size */ #define MAX_ENTRIES 128 @@ -50,10 +53,9 @@ typedef struct LuringState { struct io_uring ring; - /* io queue for submit at batch. Protected by AioContext lock. */ + /* No locking required, only accessed from AioContext home thread */ LuringQueue io_q; - /* I/O completion processing. Only runs in I/O thread. */ QEMUBH *completion_bh; } LuringState; @@ -209,6 +211,7 @@ end: * eventually runs later. Coroutines cannot be entered recursively * so avoid doing that! */ + assert(luringcb->co->ctx == s->aio_context); if (!qemu_coroutine_entered(luringcb->co)) { aio_co_wake(luringcb->co); } @@ -262,13 +265,11 @@ static int ioq_submit(LuringState *s) static void luring_process_completions_and_submit(LuringState *s) { - aio_context_acquire(s->aio_context); luring_process_completions(s); if (!s->io_q.plugged && s->io_q.in_queue > 0) { ioq_submit(s); } - aio_context_release(s->aio_context); } static void qemu_luring_completion_bh(void *opaque) @@ -306,14 +307,18 @@ static void ioq_init(LuringQueue *io_q) io_q->blocked = false; } -void luring_io_plug(BlockDriverState *bs, LuringState *s) +void luring_io_plug(void) { + AioContext *ctx = qemu_get_current_aio_context(); + LuringState *s = aio_get_linux_io_uring(ctx); trace_luring_io_plug(s); s->io_q.plugged++; } -void luring_io_unplug(BlockDriverState *bs, LuringState *s) +void luring_io_unplug(void) { + AioContext *ctx = qemu_get_current_aio_context(); + LuringState *s = aio_get_linux_io_uring(ctx); assert(s->io_q.plugged); trace_luring_io_unplug(s, s->io_q.blocked, s->io_q.plugged, s->io_q.in_queue, s->io_q.in_flight); @@ -373,10 +378,12 @@ static int luring_do_submit(int fd, LuringAIOCB *luringcb, LuringState *s, return 0; } -int coroutine_fn luring_co_submit(BlockDriverState *bs, LuringState *s, int fd, - uint64_t offset, QEMUIOVector *qiov, int type) +int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset, + QEMUIOVector *qiov, int type) { int ret; + AioContext *ctx = qemu_get_current_aio_context(); + LuringState *s = aio_get_linux_io_uring(ctx); LuringAIOCB luringcb = { .co = qemu_coroutine_self(), .ret = -EINPROGRESS, diff --git a/include/block/aio.h b/include/block/aio.h index 9e53aab..e267d91 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -211,10 +211,6 @@ struct AioContext { struct LinuxAioState *linux_aio; #endif #ifdef CONFIG_LINUX_IO_URING - /* - * State for Linux io_uring. Uses aio_context_acquire/release for - * locking. - */ struct LuringState *linux_io_uring; /* State for file descriptor monitoring using Linux io_uring */ diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h index db61447..e46a29c 100644 --- a/include/block/raw-aio.h +++ b/include/block/raw-aio.h @@ -69,12 +69,19 @@ void laio_io_unplug(uint64_t dev_max_batch); typedef struct LuringState LuringState; LuringState *luring_init(Error **errp); void luring_cleanup(LuringState *s); -int coroutine_fn luring_co_submit(BlockDriverState *bs, LuringState *s, int fd, - uint64_t offset, QEMUIOVector *qiov, int type); + +/* luring_co_submit: submit I/O requests in the thread's current AioContext. */ +int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset, + QEMUIOVector *qiov, int type); void luring_detach_aio_context(LuringState *s, AioContext *old_context); void luring_attach_aio_context(LuringState *s, AioContext *new_context); -void luring_io_plug(BlockDriverState *bs, LuringState *s); -void luring_io_unplug(BlockDriverState *bs, LuringState *s); + +/* + * luring_io_plug/unplug work in the thread's current AioContext, therefore the + * caller must ensure that they are paired in the same IOThread. + */ +void luring_io_plug(void); +void luring_io_unplug(void); #endif #ifdef _WIN32 |