qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC PATCH v2 5/6] linux-aio: On -EAGAIN, wait for completi


From: Kevin Wolf
Subject: [Qemu-devel] [RFC PATCH v2 5/6] linux-aio: On -EAGAIN, wait for completions
Date: Fri, 5 Dec 2014 17:06:07 +0100

Currently, if io_submit() return -EAGAIN, we immediately retry for three
times (which will likely still result in -EAGAIN) and then give up,
failing all requests in the queue.

Instead, keep the requests queued and try to process them as soon as
some earlier request completes. If our own queue is full and new
requests arrive, the new requests fail with -EAGAIN now (before, the
already queued ones would fail and the new ones would be queued).

Use the same logic even when the queue is not plugged. In this case
we'll not only queue the request, but immediately submit the queue. On
success, nothing changes, but in cases where the kernel returns -EAGAIN,
the requests are queued now instead of failing.

Signed-off-by: Kevin Wolf <address@hidden>
---
 block/linux-aio.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/block/linux-aio.c b/block/linux-aio.c
index 1406a71..373ec4b 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -167,9 +167,12 @@ static int ioq_submit(struct qemu_laio_state *s)
     int ret, i = 0;
     int len = s->io_q.idx;
 
-    do {
-        ret = io_submit(s->ctx, len, s->io_q.iocbs);
-    } while (i++ < 3 && ret == -EAGAIN);
+    ret = io_submit(s->ctx, len, s->io_q.iocbs);
+    if (ret == -EAGAIN) {
+        /* Leave the requests in the queue, we'll retry as soon as some request
+         * has completed */
+        return 0;
+    }
 
     /* On io_submit() failure, fail all requests in the queue */
     if (ret < 0) {
@@ -205,11 +208,15 @@ static int ioq_enqueue(struct qemu_laio_state *s, struct 
iocb *iocb)
 {
     unsigned int idx = s->io_q.idx;
 
+    if (unlikely(idx == s->io_q.size)) {
+        return -EAGAIN;
+    }
+
     s->io_q.iocbs[idx++] = iocb;
     s->io_q.idx = idx;
 
-    /* submit immediately if queue is full */
-    if (idx == s->io_q.size) {
+    /* submit immediately if queue is not plugged or full */
+    if (!s->io_q.plugged || idx == s->io_q.size) {
         return ioq_submit(s);
     } else {
         return 0;
@@ -272,11 +279,7 @@ int laio_submit_co(BlockDriverState *bs, void *aio_ctx, 
int fd,
     }
     io_set_eventfd(&laiocb.iocb, event_notifier_get_fd(&s->e));
 
-    if (!s->io_q.plugged) {
-        ret = io_submit(s->ctx, 1, &iocbs);
-    } else {
-        ret = ioq_enqueue(s, iocbs);
-    }
+    ret = ioq_enqueue(s, iocbs);
     if (ret < 0) {
         return ret;
     }
-- 
1.8.3.1




reply via email to

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