Skip to content

Commit a75e4e4

Browse files
esposemkevmw
authored andcommitted
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 <[email protected]> Message-Id: <[email protected]> Reviewed-by: Kevin Wolf <[email protected]> Reviewed-by: Stefan Hajnoczi <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent ab50533 commit a75e4e4

File tree

4 files changed

+30
-24
lines changed

4 files changed

+30
-24
lines changed

block/file-posix.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,9 +2089,8 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
20892089
type |= QEMU_AIO_MISALIGNED;
20902090
#ifdef CONFIG_LINUX_IO_URING
20912091
} else if (s->use_linux_io_uring) {
2092-
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
20932092
assert(qiov->size == bytes);
2094-
return luring_co_submit(bs, aio, s->fd, offset, qiov, type);
2093+
return luring_co_submit(bs, s->fd, offset, qiov, type);
20952094
#endif
20962095
#ifdef CONFIG_LINUX_AIO
20972096
} else if (s->use_linux_aio) {
@@ -2140,8 +2139,7 @@ static void coroutine_fn raw_co_io_plug(BlockDriverState *bs)
21402139
#endif
21412140
#ifdef CONFIG_LINUX_IO_URING
21422141
if (s->use_linux_io_uring) {
2143-
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
2144-
luring_io_plug(bs, aio);
2142+
luring_io_plug();
21452143
}
21462144
#endif
21472145
}
@@ -2156,8 +2154,7 @@ static void coroutine_fn raw_co_io_unplug(BlockDriverState *bs)
21562154
#endif
21572155
#ifdef CONFIG_LINUX_IO_URING
21582156
if (s->use_linux_io_uring) {
2159-
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
2160-
luring_io_unplug(bs, aio);
2157+
luring_io_unplug();
21612158
}
21622159
#endif
21632160
}
@@ -2181,8 +2178,7 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs)
21812178

21822179
#ifdef CONFIG_LINUX_IO_URING
21832180
if (s->use_linux_io_uring) {
2184-
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
2185-
return luring_co_submit(bs, aio, s->fd, 0, NULL, QEMU_AIO_FLUSH);
2181+
return luring_co_submit(bs, s->fd, 0, NULL, QEMU_AIO_FLUSH);
21862182
}
21872183
#endif
21882184
return raw_thread_pool_submit(bs, handle_aiocb_flush, &acb);

block/io_uring.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "qapi/error.h"
1919
#include "trace.h"
2020

21+
/* Only used for assertions. */
22+
#include "qemu/coroutine_int.h"
23+
2124
/* io_uring ring size */
2225
#define MAX_ENTRIES 128
2326

@@ -50,10 +53,9 @@ typedef struct LuringState {
5053

5154
struct io_uring ring;
5255

53-
/* io queue for submit at batch. Protected by AioContext lock. */
56+
/* No locking required, only accessed from AioContext home thread */
5457
LuringQueue io_q;
5558

56-
/* I/O completion processing. Only runs in I/O thread. */
5759
QEMUBH *completion_bh;
5860
} LuringState;
5961

@@ -209,6 +211,7 @@ static void luring_process_completions(LuringState *s)
209211
* eventually runs later. Coroutines cannot be entered recursively
210212
* so avoid doing that!
211213
*/
214+
assert(luringcb->co->ctx == s->aio_context);
212215
if (!qemu_coroutine_entered(luringcb->co)) {
213216
aio_co_wake(luringcb->co);
214217
}
@@ -262,13 +265,11 @@ static int ioq_submit(LuringState *s)
262265

263266
static void luring_process_completions_and_submit(LuringState *s)
264267
{
265-
aio_context_acquire(s->aio_context);
266268
luring_process_completions(s);
267269

268270
if (!s->io_q.plugged && s->io_q.in_queue > 0) {
269271
ioq_submit(s);
270272
}
271-
aio_context_release(s->aio_context);
272273
}
273274

274275
static void qemu_luring_completion_bh(void *opaque)
@@ -306,14 +307,18 @@ static void ioq_init(LuringQueue *io_q)
306307
io_q->blocked = false;
307308
}
308309

309-
void luring_io_plug(BlockDriverState *bs, LuringState *s)
310+
void luring_io_plug(void)
310311
{
312+
AioContext *ctx = qemu_get_current_aio_context();
313+
LuringState *s = aio_get_linux_io_uring(ctx);
311314
trace_luring_io_plug(s);
312315
s->io_q.plugged++;
313316
}
314317

315-
void luring_io_unplug(BlockDriverState *bs, LuringState *s)
318+
void luring_io_unplug(void)
316319
{
320+
AioContext *ctx = qemu_get_current_aio_context();
321+
LuringState *s = aio_get_linux_io_uring(ctx);
317322
assert(s->io_q.plugged);
318323
trace_luring_io_unplug(s, s->io_q.blocked, s->io_q.plugged,
319324
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,
373378
return 0;
374379
}
375380

376-
int coroutine_fn luring_co_submit(BlockDriverState *bs, LuringState *s, int fd,
377-
uint64_t offset, QEMUIOVector *qiov, int type)
381+
int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset,
382+
QEMUIOVector *qiov, int type)
378383
{
379384
int ret;
385+
AioContext *ctx = qemu_get_current_aio_context();
386+
LuringState *s = aio_get_linux_io_uring(ctx);
380387
LuringAIOCB luringcb = {
381388
.co = qemu_coroutine_self(),
382389
.ret = -EINPROGRESS,

include/block/aio.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,6 @@ struct AioContext {
211211
struct LinuxAioState *linux_aio;
212212
#endif
213213
#ifdef CONFIG_LINUX_IO_URING
214-
/*
215-
* State for Linux io_uring. Uses aio_context_acquire/release for
216-
* locking.
217-
*/
218214
struct LuringState *linux_io_uring;
219215

220216
/* State for file descriptor monitoring using Linux io_uring */

include/block/raw-aio.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,19 @@ void laio_io_unplug(uint64_t dev_max_batch);
6969
typedef struct LuringState LuringState;
7070
LuringState *luring_init(Error **errp);
7171
void luring_cleanup(LuringState *s);
72-
int coroutine_fn luring_co_submit(BlockDriverState *bs, LuringState *s, int fd,
73-
uint64_t offset, QEMUIOVector *qiov, int type);
72+
73+
/* luring_co_submit: submit I/O requests in the thread's current AioContext. */
74+
int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset,
75+
QEMUIOVector *qiov, int type);
7476
void luring_detach_aio_context(LuringState *s, AioContext *old_context);
7577
void luring_attach_aio_context(LuringState *s, AioContext *new_context);
76-
void luring_io_plug(BlockDriverState *bs, LuringState *s);
77-
void luring_io_unplug(BlockDriverState *bs, LuringState *s);
78+
79+
/*
80+
* luring_io_plug/unplug work in the thread's current AioContext, therefore the
81+
* caller must ensure that they are paired in the same IOThread.
82+
*/
83+
void luring_io_plug(void);
84+
void luring_io_unplug(void);
7885
#endif
7986

8087
#ifdef _WIN32

0 commit comments

Comments
 (0)