From 1919631e6b5562e474690853eca3c35610201e16 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 13 Feb 2017 14:52:31 +0100 Subject: block: explicitly acquire aiocontext in bottom halves that need it Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Reviewed-by: Fam Zheng Reviewed-by: Daniel P. Berrange Message-id: 20170213135235.12274-15-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi --- block/linux-aio.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'block/linux-aio.c') diff --git a/block/linux-aio.c b/block/linux-aio.c index 277c016cad..f7ae38af4d 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -54,10 +54,10 @@ struct LinuxAioState { io_context_t ctx; EventNotifier e; - /* io queue for submit at batch */ + /* io queue for submit at batch. Protected by AioContext lock. */ LaioQueue io_q; - /* I/O completion processing */ + /* I/O completion processing. Only runs in I/O thread. */ QEMUBH *completion_bh; int event_idx; int event_max; @@ -75,6 +75,7 @@ static inline ssize_t io_event_ret(struct io_event *ev) */ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb) { + LinuxAioState *s = laiocb->ctx; int ret; ret = laiocb->ret; @@ -93,6 +94,7 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb) } laiocb->ret = ret; + aio_context_acquire(s->aio_context); if (laiocb->co) { /* If the coroutine is already entered it must be in ioq_submit() and * will notice laio->ret has been filled in when it eventually runs @@ -106,6 +108,7 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb) laiocb->common.cb(laiocb->common.opaque, ret); qemu_aio_unref(laiocb); } + aio_context_release(s->aio_context); } /** @@ -234,9 +237,12 @@ static void qemu_laio_process_completions(LinuxAioState *s) static void qemu_laio_process_completions_and_submit(LinuxAioState *s) { qemu_laio_process_completions(s); + + aio_context_acquire(s->aio_context); if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(&s->io_q.pending)) { ioq_submit(s); } + aio_context_release(s->aio_context); } static void qemu_laio_completion_bh(void *opaque) @@ -251,9 +257,7 @@ static void qemu_laio_completion_cb(EventNotifier *e) LinuxAioState *s = container_of(e, LinuxAioState, e); if (event_notifier_test_and_clear(&s->e)) { - aio_context_acquire(s->aio_context); qemu_laio_process_completions_and_submit(s); - aio_context_release(s->aio_context); } } @@ -267,9 +271,7 @@ static bool qemu_laio_poll_cb(void *opaque) return false; } - aio_context_acquire(s->aio_context); qemu_laio_process_completions_and_submit(s); - aio_context_release(s->aio_context); return true; } @@ -459,6 +461,7 @@ void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context) { aio_set_event_notifier(old_context, &s->e, false, NULL, NULL); qemu_bh_delete(s->completion_bh); + s->aio_context = NULL; } void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context) -- cgit v1.2.3