Commit 82595da8 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Stefan Hajnoczi
Browse files

linux-aio: simplify removal of completed iocbs from the list



There is no need to do another O(n) pass on the list; the iocb to
split the list at is already available through the array we passed to
io_submit.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarKevin Wolf <kwolf@redhat.com>
Message-id: 1418305950-30924-6-git-send-email-pbonzini@redhat.com
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent de354644
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -186,9 +186,10 @@ static void ioq_init(LaioQueue *io_q)

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

    do {
        len = 0;
@@ -201,16 +202,15 @@ static void ioq_submit(struct qemu_laio_state *s)

        ret = io_submit(s->ctx, len, iocbs);
        if (ret == -EAGAIN) {
            ret = 0;
            break;
        }
        if (ret < 0) {
            abort();
        }

        for (i = 0; i < ret; i++) {
            s->io_q.n--;
            QSIMPLEQ_REMOVE_HEAD(&s->io_q.pending, next);
        }
        s->io_q.n -= ret;
        aiocb = container_of(iocbs[ret - 1], struct qemu_laiocb, iocb);
        QSIMPLEQ_SPLIT_AFTER(&s->io_q.pending, aiocb, next, &completed);
    } while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending));
    s->io_q.blocked = (s->io_q.n > 0);
}
+11 −0
Original line number Diff line number Diff line
@@ -268,6 +268,17 @@ struct { \
        (head)->sqh_last = &(head)->sqh_first;                          \
} while (/*CONSTCOND*/0)

#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do {            \
    QSIMPLEQ_INIT(removed);                                             \
    if (((removed)->sqh_first = (head)->sqh_first) != NULL) {           \
        if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) {      \
            (head)->sqh_last = &(head)->sqh_first;                      \
        }                                                               \
        (removed)->sqh_last = &(elm)->field.sqe_next;                   \
        (elm)->field.sqe_next = NULL;                                   \
    }                                                                   \
} while (/*CONSTCOND*/0)

#define QSIMPLEQ_REMOVE(head, elm, type, field) do {                    \
    if ((head)->sqh_first == (elm)) {                                   \
        QSIMPLEQ_REMOVE_HEAD((head), field);                            \