BlockDriver->bdrv_debug_event is categorized as IO callback, and it currently doesn't run in a coroutine. This makes very difficult to add the graph rdlock, since the callback traverses the block nodes graph.
Therefore use generated_co_wrapper to automatically create a wrapper with the same name. Unfortunately we cannot use a generated_co_wrapper_simple, because the function is called by mixed functions that run both in coroutine and non-coroutine context (for example blkdebug_open). Signed-off-by: Emanuele Giuseppe Esposito <eespo...@redhat.com> --- block.c | 4 +++- block/io.c | 22 +++++++++++----------- include/block/block-io.h | 7 +++++-- include/block/block_int-common.h | 4 +++- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/block.c b/block.c index afc5735b82..a2e3550d5c 100644 --- a/block.c +++ b/block.c @@ -6331,9 +6331,11 @@ BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs) return drv->bdrv_get_specific_stats(bs); } -void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event) +void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs, BlkdebugEvent event) { IO_CODE(); + assert_bdrv_graph_readable(); + if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) { return; } diff --git a/block/io.c b/block/io.c index 88da9470c3..11d2c5dcde 100644 --- a/block/io.c +++ b/block/io.c @@ -1227,7 +1227,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, goto err; } - bdrv_debug_event(bs, BLKDBG_COR_WRITE); + bdrv_co_debug_event(bs, BLKDBG_COR_WRITE); if (drv->bdrv_co_pwrite_zeroes && buffer_is_zero(bounce_buffer, pnum)) { /* FIXME: Should we (perhaps conditionally) be setting @@ -1472,10 +1472,10 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child, qemu_iovec_init_buf(&local_qiov, pad->buf, bytes); if (pad->head) { - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD); } if (pad->merge_reads && pad->tail) { - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); } ret = bdrv_aligned_preadv(child, req, req->overlap_offset, bytes, align, &local_qiov, 0, 0); @@ -1483,10 +1483,10 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child, return ret; } if (pad->head) { - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD); } if (pad->merge_reads && pad->tail) { - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL); } if (pad->merge_reads) { @@ -1497,7 +1497,7 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child, if (pad->tail) { qemu_iovec_init_buf(&local_qiov, pad->tail_buf, align); - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); ret = bdrv_aligned_preadv( child, req, req->overlap_offset + req->overlap_bytes - align, @@ -1505,7 +1505,7 @@ static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child, if (ret < 0) { return ret; } - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL); } zero_mem: @@ -1908,16 +1908,16 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, if (ret < 0) { /* Do nothing, write notifier decided to fail this request */ } else if (flags & BDRV_REQ_ZERO_WRITE) { - bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_ZERO); ret = bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags); } else if (flags & BDRV_REQ_WRITE_COMPRESSED) { ret = bdrv_driver_pwritev_compressed(bs, offset, bytes, qiov, qiov_offset); } else if (bytes <= max_transfer) { - bdrv_debug_event(bs, BLKDBG_PWRITEV); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV); ret = bdrv_driver_pwritev(bs, offset, bytes, qiov, qiov_offset, flags); } else { - bdrv_debug_event(bs, BLKDBG_PWRITEV); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV); while (bytes_remaining) { int num = MIN(bytes_remaining, max_transfer); int local_flags = flags; @@ -1940,7 +1940,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, bytes_remaining -= num; } } - bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE); + bdrv_co_debug_event(bs, BLKDBG_PWRITEV_DONE); if (ret >= 0) { ret = 0; diff --git a/include/block/block-io.h b/include/block/block-io.h index 497580fc28..176e3cc734 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -170,12 +170,15 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size); void bdrv_enable_copy_on_read(BlockDriverState *bs); void bdrv_disable_copy_on_read(BlockDriverState *bs); -void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event); +void coroutine_fn bdrv_co_debug_event(BlockDriverState *bs, + BlkdebugEvent event); +void generated_co_wrapper bdrv_debug_event(BlockDriverState *bs, + BlkdebugEvent event); #define BLKDBG_EVENT(child, evt) \ do { \ if (child) { \ - bdrv_debug_event(child->bs, evt); \ + bdrv_co_debug_event(child->bs, evt); \ } \ } while (0) diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 3e1eba518c..b509855c19 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -781,7 +781,9 @@ struct BlockDriver { BdrvCheckResult *result, BdrvCheckMode fix); - void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event); + /* Called with graph rdlock taken. */ + void coroutine_fn (*bdrv_debug_event)(BlockDriverState *bs, + BlkdebugEvent event); /* io queue for linux-aio */ void (*bdrv_io_plug)(BlockDriverState *bs); -- 2.31.1