From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45826) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XwvOu-0007L8-9b for qemu-devel@nongnu.org; Fri, 05 Dec 2014 11:06:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XwvOo-0007YM-3t for qemu-devel@nongnu.org; Fri, 05 Dec 2014 11:06:36 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40412) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XwvOn-0007Y9-Ru for qemu-devel@nongnu.org; Fri, 05 Dec 2014 11:06:30 -0500 From: Kevin Wolf Date: Fri, 5 Dec 2014 17:06:07 +0100 Message-Id: <1417795568-3201-6-git-send-email-kwolf@redhat.com> In-Reply-To: <1417795568-3201-1-git-send-email-kwolf@redhat.com> References: <1417795568-3201-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [RFC PATCH v2 5/6] linux-aio: On -EAGAIN, wait for completions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, ming.lei@canonical.com, pl@kamp.de, mreitz@redhat.com, stefanha@redhat.com, pbonzini@redhat.com 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 --- 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