[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
- [Qemu-devel] [RFC PATCH v2 0/6] linux-aio: Convert to coroutines, Kevin Wolf, 2014/12/05
- [Qemu-devel] [RFC PATCH v2 2/6] raw-posix: Convert Linux AIO submission to coroutines, Kevin Wolf, 2014/12/05
- [Qemu-devel] [RFC PATCH v2 1/6] qemu-img bench, Kevin Wolf, 2014/12/05
- [Qemu-devel] [RFC PATCH v2 3/6] linux-aio: Don't reenter request coroutine recursively, Kevin Wolf, 2014/12/05
- [Qemu-devel] [RFC PATCH v2 4/6] linux-aio: Support partial io_submits, Kevin Wolf, 2014/12/05
- [Qemu-devel] [RFC PATCH v2 5/6] linux-aio: On -EAGAIN, wait for completions,
Kevin Wolf <=
- [Qemu-devel] [RFC PATCH v2 6/6] linux-aio: Queue requests instead of returning -EAGAIN, Kevin Wolf, 2014/12/05