Commit c0e8f989 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

qed: Use a coroutine for need_check_timer



This fixes the last place where we degraded from AIO to actual blocking
synchronous I/O requests. Putting it into a coroutine means that instead
of blocking, the coroutine simply yields while doing I/O.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 48cc565e
Loading
Loading
Loading
Loading
+17 −16
Original line number Diff line number Diff line
@@ -264,11 +264,23 @@ static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
    qemu_co_enter_next(&s->allocating_write_reqs);
}

static void qed_clear_need_check(void *opaque, int ret)
static void qed_need_check_timer_entry(void *opaque)
{
    BDRVQEDState *s = opaque;
    int ret;

    if (ret) {
    /* The timer should only fire when allocating writes have drained */
    assert(!s->allocating_acb);

    trace_qed_need_check_timer_cb(s);

    qed_acquire(s);
    qed_plug_allocating_write_reqs(s);

    /* Ensure writes are on disk before clearing flag */
    ret = bdrv_co_flush(s->bs->file->bs);
    qed_release(s);
    if (ret < 0) {
        qed_unplug_allocating_write_reqs(s);
        return;
    }
@@ -279,25 +291,14 @@ static void qed_clear_need_check(void *opaque, int ret)

    qed_unplug_allocating_write_reqs(s);

    ret = bdrv_flush(s->bs);
    ret = bdrv_co_flush(s->bs);
    (void) ret;
}

static void qed_need_check_timer_cb(void *opaque)
{
    BDRVQEDState *s = opaque;

    /* The timer should only fire when allocating writes have drained */
    assert(!s->allocating_acb);

    trace_qed_need_check_timer_cb(s);

    qed_acquire(s);
    qed_plug_allocating_write_reqs(s);

    /* Ensure writes are on disk before clearing flag */
    bdrv_aio_flush(s->bs->file->bs, qed_clear_need_check, s);
    qed_release(s);
    Coroutine *co = qemu_coroutine_create(qed_need_check_timer_entry, opaque);
    qemu_coroutine_enter(co);
}

void qed_acquire(BDRVQEDState *s)