diff mbox

[01/13] block/linux-aio: allocate io queue dynamically

Message ID 1415518978-2837-2-git-send-email-ming.lei@canonical.com
State New
Headers show

Commit Message

Ming Lei Nov. 9, 2014, 7:42 a.m. UTC
This patch allocates io queue dynamically so that we
can support aio_context wide io queue in the following
patch.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 block/linux-aio.c |   66 +++++++++++++++++++++++++++++++++--------------------
 1 file changed, 41 insertions(+), 25 deletions(-)
diff mbox

Patch

diff --git a/block/linux-aio.c b/block/linux-aio.c
index b12da25..b9db28e 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -57,7 +57,7 @@  struct qemu_laio_state {
     EventNotifier e;
 
     /* io queue for submit at batch */
-    LaioQueue io_q;
+    LaioQueue *io_q;
 
     /* I/O completion processing */
     QEMUBH *completion_bh;
@@ -146,8 +146,8 @@  static void qemu_laio_completion_bh(void *opaque)
 
 static void qemu_laio_start_retry(struct qemu_laio_state *s)
 {
-    if (s->io_q.idx)
-        qemu_bh_schedule(s->io_q.retry);
+    if (s->io_q->idx)
+        qemu_bh_schedule(s->io_q->retry);
 }
 
 static void qemu_laio_completion_cb(EventNotifier *e)
@@ -197,8 +197,8 @@  static void ioq_init(LaioQueue *io_q)
 static void abort_queue(struct qemu_laio_state *s)
 {
     int i;
-    for (i = 0; i < s->io_q.idx; i++) {
-        struct qemu_laiocb *laiocb = container_of(s->io_q.iocbs[i],
+    for (i = 0; i < s->io_q->idx; i++) {
+        struct qemu_laiocb *laiocb = container_of(s->io_q->iocbs[i],
                                                   struct qemu_laiocb,
                                                   iocb);
         laiocb->ret = -EIO;
@@ -209,14 +209,14 @@  static void abort_queue(struct qemu_laio_state *s)
 static int ioq_submit(struct qemu_laio_state *s, bool enqueue)
 {
     int ret, i = 0;
-    int len = s->io_q.idx;
+    int len = s->io_q->idx;
     int j = 0;
 
     if (!len) {
         return 0;
     }
 
-    ret = io_submit(s->ctx, len, s->io_q.iocbs);
+    ret = io_submit(s->ctx, len, s->io_q->iocbs);
     if (ret == -EAGAIN) { /* retry in following completion cb */
         return 0;
     } else if (ret < 0) {
@@ -232,7 +232,7 @@  static int ioq_submit(struct qemu_laio_state *s, bool enqueue)
     }
 
     for (i = ret; i < len; i++) {
-        s->io_q.iocbs[j++] = s->io_q.iocbs[i];
+        s->io_q->iocbs[j++] = s->io_q->iocbs[i];
     }
 
  out:
@@ -240,7 +240,7 @@  static int ioq_submit(struct qemu_laio_state *s, bool enqueue)
      * update io queue, for partial completion, retry will be
      * started automatically in following completion cb.
      */
-    s->io_q.idx -= ret;
+    s->io_q->idx -= ret;
 
     return ret;
 }
@@ -253,22 +253,22 @@  static void ioq_submit_retry(void *opaque)
 
 static int ioq_enqueue(struct qemu_laio_state *s, struct iocb *iocb)
 {
-    unsigned int idx = s->io_q.idx;
+    unsigned int idx = s->io_q->idx;
 
-    if (unlikely(idx == s->io_q.size)) {
+    if (unlikely(idx == s->io_q->size)) {
         return -1;
     }
 
-    s->io_q.iocbs[idx++] = iocb;
-    s->io_q.idx = idx;
+    s->io_q->iocbs[idx++] = iocb;
+    s->io_q->idx = idx;
 
     /* don't submit until next completion for -EAGAIN of non plug case */
-    if (unlikely(!s->io_q.plugged)) {
+    if (unlikely(!s->io_q->plugged)) {
         return 0;
     }
 
     /* submit immediately if queue depth is above 2/3 */
-    if (idx > s->io_q.size * 2 / 3) {
+    if (idx > s->io_q->size * 2 / 3) {
         return ioq_submit(s, true);
     }
 
@@ -279,7 +279,7 @@  void laio_io_plug(BlockDriverState *bs, void *aio_ctx)
 {
     struct qemu_laio_state *s = aio_ctx;
 
-    s->io_q.plugged++;
+    s->io_q->plugged++;
 }
 
 int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
@@ -287,13 +287,13 @@  int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
     struct qemu_laio_state *s = aio_ctx;
     int ret = 0;
 
-    assert(s->io_q.plugged > 0 || !unplug);
+    assert(s->io_q->plugged > 0 || !unplug);
 
-    if (unplug && --s->io_q.plugged > 0) {
+    if (unplug && --s->io_q->plugged > 0) {
         return 0;
     }
 
-    if (s->io_q.idx > 0) {
+    if (s->io_q->idx > 0) {
         ret = ioq_submit(s, false);
     }
 
@@ -333,10 +333,10 @@  BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
     }
     io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
 
-    if (!s->io_q.plugged) {
+    if (!s->io_q->plugged) {
         int ret;
 
-        if (!s->io_q.idx) {
+        if (!s->io_q->idx) {
             ret = io_submit(s->ctx, 1, &iocbs);
         } else {
             ret = -EAGAIN;
@@ -364,20 +364,38 @@  out_free_aiocb:
     return NULL;
 }
 
+static LaioQueue *laio_alloc_ioq(AioContext *ctx, struct qemu_laio_state *s)
+{
+    LaioQueue *ioq = g_malloc0(sizeof(*ioq));
+
+    ioq_init(ioq);
+    ioq->retry = aio_bh_new(ctx, ioq_submit_retry, s);
+    return ioq;
+}
+
+static void laio_free_ioq(struct qemu_laio_state *s, LaioQueue *ioq)
+{
+    qemu_bh_delete(ioq->retry);
+    g_free(ioq);
+    s->io_q = NULL;
+}
+
 void laio_detach_aio_context(void *s_, AioContext *old_context)
 {
     struct qemu_laio_state *s = s_;
 
     aio_set_event_notifier(old_context, &s->e, NULL);
     qemu_bh_delete(s->completion_bh);
-    qemu_bh_delete(s->io_q.retry);
+
+    laio_free_ioq(s, s->io_q);
 }
 
 void laio_attach_aio_context(void *s_, AioContext *new_context)
 {
     struct qemu_laio_state *s = s_;
 
-    s->io_q.retry = aio_bh_new(new_context, ioq_submit_retry, s);
+    s->io_q = laio_alloc_ioq(new_context, s);
+
     s->completion_bh = aio_bh_new(new_context, qemu_laio_completion_bh, s);
     aio_set_event_notifier(new_context, &s->e, qemu_laio_completion_cb);
 }
@@ -395,8 +413,6 @@  void *laio_init(void)
         goto out_close_efd;
     }
 
-    ioq_init(&s->io_q);
-
     return s;
 
 out_close_efd: