[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 05/16] mirror: use bottom half to re-enter corout
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH v2 05/16] mirror: use bottom half to re-enter coroutine |
Date: |
Wed, 16 Mar 2016 15:16:46 +0100 |
Signed-off-by: Paolo Bonzini <address@hidden>
---
v1->v2: use aio_bh_new() [Fam]
block/mirror.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 9635fa8..2c7874d 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -72,6 +72,7 @@ typedef struct MirrorOp {
QEMUIOVector qiov;
int64_t sector_num;
int nb_sectors;
+ QEMUBH *co_enter_bh;
} MirrorOp;
static BlockErrorAction mirror_error_action(MirrorBlockJob *s, bool read,
@@ -87,6 +88,18 @@ static BlockErrorAction mirror_error_action(MirrorBlockJob
*s, bool read,
}
}
+static void mirror_bh_cb(void *opaque)
+{
+ MirrorOp *op = opaque;
+ MirrorBlockJob *s = op->s;
+
+ qemu_bh_delete(op->co_enter_bh);
+ g_free(op);
+ if (s->waiting_for_io) {
+ qemu_coroutine_enter(s->common.co, NULL);
+ }
+}
+
static void mirror_iteration_done(MirrorOp *op, int ret)
{
MirrorBlockJob *s = op->s;
@@ -117,11 +130,14 @@ static void mirror_iteration_done(MirrorOp *op, int ret)
}
qemu_iovec_destroy(&op->qiov);
- g_free(op);
- if (s->waiting_for_io) {
- qemu_coroutine_enter(s->common.co, NULL);
- }
+ /* The I/O operation is not finished until the callback returns.
+ * If we call qemu_coroutine_enter here, there is the possibility
+ * of a deadlock when the coroutine calls bdrv_drained_begin.
+ */
+ op->co_enter_bh = aio_bh_new(bdrv_get_aio_context(s->target),
+ mirror_bh_cb, op);
+ qemu_bh_schedule(op->co_enter_bh);
}
static void mirror_write_complete(void *opaque, int ret)
--
1.8.3.1
- [Qemu-devel] [PATCH v2 00/16] AioContext fine-grained locking, part 1 of 3, including bdrv_drain rewrite, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 01/16] block: make bdrv_start_throttled_reqs return void, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 03/16] block: introduce bdrv_no_throttling_begin/end, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 02/16] block: move restarting of throttled reqs to block/throttle-groups.c, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 04/16] block: plug whole tree at once, introduce bdrv_io_unplugged_begin/end, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 06/16] block: add BDS field to count in-flight requests, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 05/16] mirror: use bottom half to re-enter coroutine,
Paolo Bonzini <=
- [Qemu-devel] [PATCH v2 07/16] block: change drain to look only at one child at a time, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 09/16] block: wait for all pending I/O when doing synchronous requests, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 12/16] aio: introduce aio_context_in_iothread, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 11/16] sheepdog: disable dataplane, Paolo Bonzini, 2016/03/16
- [Qemu-devel] [PATCH v2 08/16] blockjob: introduce .drain callback for jobs, Paolo Bonzini, 2016/03/16