Commit 8b9dfe90 authored by Peter Lieven's avatar Peter Lieven Committed by Paolo Bonzini
Browse files

block/iscsi: use a bh to schedule co reentrance



this fixes a potential segfault and performance regression.

If the coroutine is reentered directly in the iscsi_co_generic_cb
iscsi_process_{read,write} are interrupted and reentered any
time later. One the one hand this could happen after an iscsi_close
where the iscsi context is already gone (segfault). On the
other hand this limits the number of processed callbacks
in each aio_dispatch to one (potential performance regression).

Cc: qemu-stable@nongnu.org
Signed-off-by: default avatarPeter Lieven <pl@kamp.de>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent e157b8fd
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ typedef struct IscsiTask {
    int do_retry;
    struct scsi_task *task;
    Coroutine *co;
    QEMUBH *bh;
} IscsiTask;

typedef struct IscsiAIOCB {
@@ -123,6 +124,13 @@ iscsi_schedule_bh(IscsiAIOCB *acb)
    qemu_bh_schedule(acb->bh);
}

static void iscsi_co_generic_bh_cb(void *opaque)
{
    struct IscsiTask *iTask = opaque;
    qemu_bh_delete(iTask->bh);
    qemu_coroutine_enter(iTask->co, NULL);
}

static void
iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
                        void *command_data, void *opaque)
@@ -147,7 +155,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,

out:
    if (iTask->co) {
        qemu_coroutine_enter(iTask->co, NULL);
        iTask->bh = qemu_bh_new(iscsi_co_generic_bh_cb, iTask);
        qemu_bh_schedule(iTask->bh);
    }
}