From 81f730d4d0e8af9c0211c3fedf406df0046341a9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 7 Apr 2023 17:33:03 +0200 Subject: block, block-backend: write some hot coroutine wrappers by hand The introduction of the graph lock is causing blk_get_geometry, a hot function used in the I/O path, to create a coroutine. However, the only part that really needs to run in coroutine context is the call to bdrv_co_refresh_total_sectors, which in turn only happens in the rare case of host CD-ROM devices. So, write by hand the three wrappers on the path from blk_co_get_geometry to bdrv_co_refresh_total_sectors, so that the coroutine wrapper is only created if bdrv_nb_sectors actually calls bdrv_refresh_total_sectors. Reported-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-Id: <20230407153303.391121-9-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/block-backend.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'block/block-backend.c') diff --git a/block/block-backend.c b/block/block-backend.c index cf58d4d1b7..55efc735b4 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1629,6 +1629,23 @@ int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk) } } +/* + * This wrapper is written by hand because this function is in the hot I/O path, + * via blk_get_geometry. + */ +int64_t coroutine_mixed_fn blk_nb_sectors(BlockBackend *blk) +{ + BlockDriverState *bs = blk_bs(blk); + + IO_CODE(); + + if (!bs) { + return -ENOMEDIUM; + } else { + return bdrv_nb_sectors(bs); + } +} + /* return 0 as number of sectors if no device present or error */ void coroutine_fn blk_co_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr) @@ -1637,6 +1654,16 @@ void coroutine_fn blk_co_get_geometry(BlockBackend *blk, *nb_sectors_ptr = ret < 0 ? 0 : ret; } +/* + * This wrapper is written by hand because this function is in the hot I/O path. + */ +void coroutine_mixed_fn blk_get_geometry(BlockBackend *blk, + uint64_t *nb_sectors_ptr) +{ + int64_t ret = blk_nb_sectors(blk); + *nb_sectors_ptr = ret < 0 ? 0 : ret; +} + BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset, QEMUIOVector *qiov, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque) -- cgit v1.2.3