mirror of https://github.com/xemu-project/xemu.git
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>
This commit is contained in:
parent
ab50533b69
commit
a75e4e4365
|
@ -2089,9 +2089,8 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
|
||||||
type |= QEMU_AIO_MISALIGNED;
|
type |= QEMU_AIO_MISALIGNED;
|
||||||
#ifdef CONFIG_LINUX_IO_URING
|
#ifdef CONFIG_LINUX_IO_URING
|
||||||
} else if (s->use_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);
|
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
|
#endif
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
} else if (s->use_linux_aio) {
|
} else if (s->use_linux_aio) {
|
||||||
|
@ -2140,8 +2139,7 @@ static void coroutine_fn raw_co_io_plug(BlockDriverState *bs)
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_LINUX_IO_URING
|
#ifdef CONFIG_LINUX_IO_URING
|
||||||
if (s->use_linux_io_uring) {
|
if (s->use_linux_io_uring) {
|
||||||
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
|
luring_io_plug();
|
||||||
luring_io_plug(bs, aio);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2156,8 +2154,7 @@ static void coroutine_fn raw_co_io_unplug(BlockDriverState *bs)
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_LINUX_IO_URING
|
#ifdef CONFIG_LINUX_IO_URING
|
||||||
if (s->use_linux_io_uring) {
|
if (s->use_linux_io_uring) {
|
||||||
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
|
luring_io_unplug();
|
||||||
luring_io_unplug(bs, aio);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2181,8 +2178,7 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs)
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_IO_URING
|
#ifdef CONFIG_LINUX_IO_URING
|
||||||
if (s->use_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, s->fd, 0, NULL, QEMU_AIO_FLUSH);
|
||||||
return luring_co_submit(bs, aio, s->fd, 0, NULL, QEMU_AIO_FLUSH);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return raw_thread_pool_submit(bs, handle_aiocb_flush, &acb);
|
return raw_thread_pool_submit(bs, handle_aiocb_flush, &acb);
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
|
/* Only used for assertions. */
|
||||||
|
#include "qemu/coroutine_int.h"
|
||||||
|
|
||||||
/* io_uring ring size */
|
/* io_uring ring size */
|
||||||
#define MAX_ENTRIES 128
|
#define MAX_ENTRIES 128
|
||||||
|
|
||||||
|
@ -50,10 +53,9 @@ typedef struct LuringState {
|
||||||
|
|
||||||
struct io_uring ring;
|
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;
|
LuringQueue io_q;
|
||||||
|
|
||||||
/* I/O completion processing. Only runs in I/O thread. */
|
|
||||||
QEMUBH *completion_bh;
|
QEMUBH *completion_bh;
|
||||||
} LuringState;
|
} LuringState;
|
||||||
|
|
||||||
|
@ -209,6 +211,7 @@ end:
|
||||||
* eventually runs later. Coroutines cannot be entered recursively
|
* eventually runs later. Coroutines cannot be entered recursively
|
||||||
* so avoid doing that!
|
* so avoid doing that!
|
||||||
*/
|
*/
|
||||||
|
assert(luringcb->co->ctx == s->aio_context);
|
||||||
if (!qemu_coroutine_entered(luringcb->co)) {
|
if (!qemu_coroutine_entered(luringcb->co)) {
|
||||||
aio_co_wake(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)
|
static void luring_process_completions_and_submit(LuringState *s)
|
||||||
{
|
{
|
||||||
aio_context_acquire(s->aio_context);
|
|
||||||
luring_process_completions(s);
|
luring_process_completions(s);
|
||||||
|
|
||||||
if (!s->io_q.plugged && s->io_q.in_queue > 0) {
|
if (!s->io_q.plugged && s->io_q.in_queue > 0) {
|
||||||
ioq_submit(s);
|
ioq_submit(s);
|
||||||
}
|
}
|
||||||
aio_context_release(s->aio_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qemu_luring_completion_bh(void *opaque)
|
static void qemu_luring_completion_bh(void *opaque)
|
||||||
|
@ -306,14 +307,18 @@ static void ioq_init(LuringQueue *io_q)
|
||||||
io_q->blocked = false;
|
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);
|
trace_luring_io_plug(s);
|
||||||
s->io_q.plugged++;
|
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);
|
assert(s->io_q.plugged);
|
||||||
trace_luring_io_unplug(s, s->io_q.blocked, 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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int coroutine_fn luring_co_submit(BlockDriverState *bs, LuringState *s, int fd,
|
int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset,
|
||||||
uint64_t offset, QEMUIOVector *qiov, int type)
|
QEMUIOVector *qiov, int type)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
AioContext *ctx = qemu_get_current_aio_context();
|
||||||
|
LuringState *s = aio_get_linux_io_uring(ctx);
|
||||||
LuringAIOCB luringcb = {
|
LuringAIOCB luringcb = {
|
||||||
.co = qemu_coroutine_self(),
|
.co = qemu_coroutine_self(),
|
||||||
.ret = -EINPROGRESS,
|
.ret = -EINPROGRESS,
|
||||||
|
|
|
@ -211,10 +211,6 @@ struct AioContext {
|
||||||
struct LinuxAioState *linux_aio;
|
struct LinuxAioState *linux_aio;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_LINUX_IO_URING
|
#ifdef CONFIG_LINUX_IO_URING
|
||||||
/*
|
|
||||||
* State for Linux io_uring. Uses aio_context_acquire/release for
|
|
||||||
* locking.
|
|
||||||
*/
|
|
||||||
struct LuringState *linux_io_uring;
|
struct LuringState *linux_io_uring;
|
||||||
|
|
||||||
/* State for file descriptor monitoring using Linux io_uring */
|
/* State for file descriptor monitoring using Linux io_uring */
|
||||||
|
|
|
@ -69,12 +69,19 @@ void laio_io_unplug(uint64_t dev_max_batch);
|
||||||
typedef struct LuringState LuringState;
|
typedef struct LuringState LuringState;
|
||||||
LuringState *luring_init(Error **errp);
|
LuringState *luring_init(Error **errp);
|
||||||
void luring_cleanup(LuringState *s);
|
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_detach_aio_context(LuringState *s, AioContext *old_context);
|
||||||
void luring_attach_aio_context(LuringState *s, AioContext *new_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
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
Loading…
Reference in New Issue