qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 11/13] block/linux-aio: reallocate I/O resources whe


From: Ming Lei
Subject: [Qemu-devel] [PATCH 11/13] block/linux-aio: reallocate I/O resources when aio attached
Date: Sun, 9 Nov 2014 15:42:56 +0800

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 <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]