Commit 43f2376e authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Stefan Hajnoczi
Browse files

linux-aio: track whether the queue is blocked



Avoid that unplug submits requests when io_submit reported that it
couldn't accept more; at the same time, try more io_submit calls if it
could handle the whole set of requests that were passed, so that the
"blocked" flag is reset as soon as possible.

After the previous patch, laio_submit already tried to avoid submitting
requests to a blocked queue, by comparing s->io_q.idx with "==" instead
of the more natural ">=".  Switch to the simpler expression now that we
have the "blocked" flag.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarKevin Wolf <kwolf@redhat.com>
Message-id: 1418305950-30924-3-git-send-email-pbonzini@redhat.com
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 28b24087
Loading
Loading
Loading
Loading
+27 −20
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct qemu_laiocb {
typedef struct {
    int plugged;
    unsigned int idx;
    bool blocked;
    QSIMPLEQ_HEAD(, qemu_laiocb) pending;
} LaioQueue;

@@ -180,15 +181,17 @@ static void ioq_init(LaioQueue *io_q)
    QSIMPLEQ_INIT(&io_q->pending);
    io_q->plugged = 0;
    io_q->idx = 0;
    io_q->blocked = false;
}

static int ioq_submit(struct qemu_laio_state *s)
{
    int ret, i;
    int len = 0;
    int ret, i, len;
    struct qemu_laiocb *aiocb;
    struct iocb *iocbs[MAX_QUEUED_IO];

    do {
        len = 0;
        QSIMPLEQ_FOREACH(aiocb, &s->io_q.pending, next) {
            iocbs[len++] = &aiocb->iocb;
            if (len == MAX_QUEUED_IO) {
@@ -208,6 +211,9 @@ static int ioq_submit(struct qemu_laio_state *s)
            s->io_q.idx--;
            QSIMPLEQ_REMOVE_HEAD(&s->io_q.pending, next);
        }
    } while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending));
    s->io_q.blocked = (s->io_q.idx > 0);

    return ret;
}

@@ -229,7 +235,7 @@ int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
        return 0;
    }

    if (!QSIMPLEQ_EMPTY(&s->io_q.pending)) {
    if (!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
        ret = ioq_submit(s);
    }

@@ -271,7 +277,8 @@ BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,

    QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
    s->io_q.idx++;
    if (s->io_q.idx == (s->io_q.plugged ? MAX_QUEUED_IO : 1)) {
    if (!s->io_q.blocked &&
        (!s->io_q.plugged || s->io_q.idx >= MAX_QUEUED_IO)) {
        ioq_submit(s);
    }
    return &laiocb->common;