We want the BDS event loop to run exclusively in the iothread that owns the BDS's AioContext. This function and macro provides the synchronization between the two event loops.
Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- block/block-backend.c | 7 +------ block/io.c | 47 +++++++++++------------------------------------ block/qed-table.c | 16 ++++------------ block/qed.c | 4 +++- include/block/block.h | 9 +++++++++ include/block/block_int.h | 1 + 6 files changed, 29 insertions(+), 55 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index 234df1e..c5c2597 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -878,7 +878,6 @@ static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, int64_t bytes, CoroutineEntry co_entry, BdrvRequestFlags flags) { - AioContext *aio_context; QEMUIOVector qiov; struct iovec iov; Coroutine *co; @@ -900,11 +899,7 @@ static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf, co = qemu_coroutine_create(co_entry, &rwco); qemu_coroutine_enter(co); - - aio_context = blk_get_aio_context(blk); - while (rwco.ret == NOT_DONE) { - aio_poll(aio_context, true); - } + bdrv_poll_while(blk_bs(blk), rwco.ret == NOT_DONE); return rwco.ret; } diff --git a/block/io.c b/block/io.c index afec968..7d3dcfc 100644 --- a/block/io.c +++ b/block/io.c @@ -156,23 +156,12 @@ bool bdrv_requests_pending(BlockDriverState *bs) return false; } -static bool bdrv_drain_poll(BlockDriverState *bs) -{ - bool waited = false; - - while (atomic_read(&bs->in_flight) > 0) { - aio_poll(bdrv_get_aio_context(bs), true); - waited = true; - } - return waited; -} - static bool bdrv_drain_recurse(BlockDriverState *bs) { BdrvChild *child; bool waited; - waited = bdrv_drain_poll(bs); + waited = bdrv_poll_while(bs, atomic_read(&bs->in_flight) > 0); if (bs->drv && bs->drv->bdrv_drain) { bs->drv->bdrv_drain(bs); @@ -485,9 +474,14 @@ void bdrv_inc_in_flight(BlockDriverState *bs) atomic_inc(&bs->in_flight); } +void bdrv_wakeup(BlockDriverState *bs) +{ +} + void bdrv_dec_in_flight(BlockDriverState *bs) { atomic_dec(&bs->in_flight); + bdrv_wakeup(bs); } static bool coroutine_fn wait_serialising_requests(BdrvTrackedRequest *self) @@ -597,13 +591,9 @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offset, /* Fast-path if already in coroutine context */ bdrv_rw_co_entry(&rwco); } else { - AioContext *aio_context = bdrv_get_aio_context(child->bs); - co = qemu_coroutine_create(bdrv_rw_co_entry, &rwco); qemu_coroutine_enter(co); - while (rwco.ret == NOT_DONE) { - aio_poll(aio_context, true); - } + bdrv_poll_while(child->bs, rwco.ret == NOT_DONE); } return rwco.ret; } @@ -1845,14 +1835,10 @@ int64_t bdrv_get_block_status_above(BlockDriverState *bs, /* Fast-path if already in coroutine context */ bdrv_get_block_status_above_co_entry(&data); } else { - AioContext *aio_context = bdrv_get_aio_context(bs); - co = qemu_coroutine_create(bdrv_get_block_status_above_co_entry, &data); qemu_coroutine_enter(co); - while (!data.done) { - aio_poll(aio_context, true); - } + bdrv_poll_while(bs, !data.done); } return data.ret; } @@ -2411,13 +2397,9 @@ int bdrv_flush(BlockDriverState *bs) /* Fast-path if already in coroutine context */ bdrv_flush_co_entry(&flush_co); } else { - AioContext *aio_context = bdrv_get_aio_context(bs); - co = qemu_coroutine_create(bdrv_flush_co_entry, &flush_co); qemu_coroutine_enter(co); - while (flush_co.ret == NOT_DONE) { - aio_poll(aio_context, true); - } + bdrv_poll_while(bs, flush_co.ret == NOT_DONE); } return flush_co.ret; @@ -2543,13 +2525,9 @@ int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int count) /* Fast-path if already in coroutine context */ bdrv_pdiscard_co_entry(&rwco); } else { - AioContext *aio_context = bdrv_get_aio_context(bs); - co = qemu_coroutine_create(bdrv_pdiscard_co_entry, &rwco); qemu_coroutine_enter(co); - while (rwco.ret == NOT_DONE) { - aio_poll(aio_context, true); - } + bdrv_poll_while(bs, rwco.ret == NOT_DONE); } return rwco.ret; @@ -2608,11 +2586,8 @@ int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) bdrv_co_ioctl_entry(&data); } else { Coroutine *co = qemu_coroutine_create(bdrv_co_ioctl_entry, &data); - qemu_coroutine_enter(co); - while (data.ret == -EINPROGRESS) { - aio_poll(bdrv_get_aio_context(bs), true); - } + bdrv_poll_while(bs, data.ret == -EINPROGRESS); } return data.ret; } diff --git a/block/qed-table.c b/block/qed-table.c index 1a731df..b7d53ce 100644 --- a/block/qed-table.c +++ b/block/qed-table.c @@ -174,9 +174,7 @@ int qed_read_l1_table_sync(BDRVQEDState *s) qed_read_table(s, s->header.l1_table_offset, s->l1_table, qed_sync_cb, &ret); - while (ret == -EINPROGRESS) { - aio_poll(bdrv_get_aio_context(s->bs), true); - } + bdrv_poll_while(s->bs, ret == -EINPROGRESS); return ret; } @@ -195,9 +193,7 @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, int ret = -EINPROGRESS; qed_write_l1_table(s, index, n, qed_sync_cb, &ret); - while (ret == -EINPROGRESS) { - aio_poll(bdrv_get_aio_context(s->bs), true); - } + bdrv_poll_while(s->bs, ret == -EINPROGRESS); return ret; } @@ -268,9 +264,7 @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset int ret = -EINPROGRESS; qed_read_l2_table(s, request, offset, qed_sync_cb, &ret); - while (ret == -EINPROGRESS) { - aio_poll(bdrv_get_aio_context(s->bs), true); - } + bdrv_poll_while(s->bs, ret == -EINPROGRESS); return ret; } @@ -290,9 +284,7 @@ int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, int ret = -EINPROGRESS; qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret); - while (ret == -EINPROGRESS) { - aio_poll(bdrv_get_aio_context(s->bs), true); - } + bdrv_poll_while(s->bs, ret == -EINPROGRESS); return ret; } diff --git a/block/qed.c b/block/qed.c index 1a7ef0a..dcb5fb9 100644 --- a/block/qed.c +++ b/block/qed.c @@ -354,7 +354,9 @@ static void qed_start_need_check_timer(BDRVQEDState *s) static void qed_cancel_need_check_timer(BDRVQEDState *s) { trace_qed_cancel_need_check_timer(s); - timer_del(s->need_check_timer); + if (s->need_check_timer) { + timer_del(s->need_check_timer); + } } static void bdrv_qed_detach_aio_context(BlockDriverState *bs) diff --git a/include/block/block.h b/include/block/block.h index 107c603..876a1e7 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -340,6 +340,15 @@ void bdrv_drain(BlockDriverState *bs); void coroutine_fn bdrv_co_drain(BlockDriverState *bs); void bdrv_drain_all(void); +#define bdrv_poll_while(bs, cond) ({ \ + bool waited_ = false; \ + BlockDriverState *bs_ = (bs); \ + while ((cond)) { \ + aio_poll(bdrv_get_aio_context(bs_), true); \ + waited_ = true; \ + } \ + waited_; }) + int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int count); int bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, int count); int bdrv_has_zero_init_1(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index 5a7308b..11f877b 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -786,6 +786,7 @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in); void bdrv_inc_in_flight(BlockDriverState *bs); void bdrv_dec_in_flight(BlockDriverState *bs); +void bdrv_wakeup(BlockDriverState *bs); void blockdev_close_all_bdrv_states(void); -- 2.7.4