From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38082) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnNAC-0001Xa-Nu for qemu-devel@nongnu.org; Sun, 09 Nov 2014 02:44:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XnNA6-00015t-KH for qemu-devel@nongnu.org; Sun, 09 Nov 2014 02:43:56 -0500 Received: from mail-pa0-f46.google.com ([209.85.220.46]:58608) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnNA6-00015p-CL for qemu-devel@nongnu.org; Sun, 09 Nov 2014 02:43:50 -0500 Received: by mail-pa0-f46.google.com with SMTP id lf10so6178363pab.19 for ; Sat, 08 Nov 2014 23:43:49 -0800 (PST) From: Ming Lei Date: Sun, 9 Nov 2014 15:42:56 +0800 Message-Id: <1415518978-2837-12-git-send-email-ming.lei@canonical.com> In-Reply-To: <1415518978-2837-1-git-send-email-ming.lei@canonical.com> References: <1415518978-2837-1-git-send-email-ming.lei@canonical.com> Subject: [Qemu-devel] [PATCH 11/13] block/linux-aio: reallocate I/O resources when aio attached List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, Peter Maydell , Paolo Bonzini , Stefan Hajnoczi , Kevin Wolf Cc: Ming Lei , Fam Zheng First event notifier and qemu BH is associated with aio context, so it should be reallocated for making these handlers running in the current attached aio context. Secondly when new 'bs' is attached, we need to allocate more io resources for performance purpose. This patch only does the reallocation if there aren't any pending I/O. Signed-off-by: Ming Lei --- block/linux-aio.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/block/linux-aio.c b/block/linux-aio.c index e219b80..c5a88e8 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -59,6 +59,7 @@ typedef struct LaioTrackedBs { /* lifetime: between aio_attach and aio_detach */ struct qemu_laio_state { + unsigned long io_pending; io_context_t ctx; EventNotifier e; @@ -75,6 +76,7 @@ struct qemu_laio_state { /* All BS in the list shared this 'qemu_laio_state' */ QLIST_HEAD(, LaioTrackedBs) tracked_bs; int nr_bs; + bool need_realloc; AioContext *aio_context; }; @@ -82,6 +84,8 @@ typedef struct { struct qemu_laio_state *state; } QemuLaioState; +static void laio_realloc_resources(struct qemu_laio_state *s); + static inline ssize_t io_event_ret(struct io_event *ev) { return (ssize_t)(((uint64_t)ev->res2 << 32) | ev->res); @@ -110,6 +114,8 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s, } } laiocb->common.cb(laiocb->common.opaque, ret); + s->io_pending--; + laio_realloc_resources(s); qemu_aio_unref(laiocb); } @@ -193,6 +199,8 @@ static void laio_cancel(BlockAIOCB *blockacb) } laiocb->common.cb(laiocb->common.opaque, laiocb->ret); + laiocb->aio_state->io_pending--; + laio_realloc_resources(laiocb->aio_state); /* check if there are requests in io queue */ qemu_laio_start_retry(laiocb->aio_state); @@ -378,6 +386,8 @@ BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, goto out_free_aiocb; } } + + s->io_pending++; return &laiocb->common; out_free_aiocb: @@ -429,6 +439,10 @@ static void laio_free_resources(struct qemu_laio_state *s) { LaioQueue *ioq = s->io_q; + if (!ioq) { + return; + } + aio_set_event_notifier(s->aio_context, &s->e, NULL); qemu_bh_delete(s->completion_bh); @@ -441,6 +455,8 @@ static void laio_free_resources(struct qemu_laio_state *s) if (io_destroy(s->ctx) != 0) { fprintf(stderr, "%s: destroy AIO context %p failed\n", __func__, &s->ctx); + } else { + s->ctx = 0; } } @@ -473,6 +489,17 @@ static void laio_state_free(struct qemu_laio_state *s, AioContext *context) g_free(s); } +static void laio_realloc_resources(struct qemu_laio_state *s) +{ + if (unlikely(s->need_realloc) && unlikely(!s->io_pending) && + !s->io_q->plugged) { + laio_free_resources(s); + laio_alloc_resources(s->aio_context, s); + + s->need_realloc = false; + } +} + void laio_detach_aio_context(void *s_, BlockDriverState *bs, AioContext *old_context) { @@ -493,6 +520,7 @@ void laio_detach_aio_context(void *s_, BlockDriverState *bs, tbs = QLIST_FIRST(&qs->state->tracked_bs); old_context->master_aio_bs = tbs->bs; } + qs->state->need_realloc = true; return; } @@ -513,11 +541,13 @@ void laio_attach_aio_context(void *s_, BlockDriverState *bs, qs->state->aio_context = new_context; } else { qs->state = new_context->opaque; + qs->state->need_realloc = true; } tbs->bs = bs; QLIST_INSERT_HEAD(&qs->state->tracked_bs, tbs, list); qs->state->nr_bs++; + qs->state->aio_context = new_context; } void *laio_init(void) -- 1.7.9.5