This patch implements .bdrv_submit_io_queue callback for linux-aio Block Drivers, so that submitting I/O at batch can be supported on linux-aio.
Signed-off-by: Ming Lei <ming....@canonical.com> --- block/linux-aio.c | 32 ++++++++++++++++++++++++++++++-- block/raw-aio.h | 1 + block/raw-posix.c | 16 ++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/block/linux-aio.c b/block/linux-aio.c index f0a2c08..12f56d8 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -11,6 +11,7 @@ #include "block/aio.h" #include "qemu/queue.h" #include "block/raw-aio.h" +#include "block/block_int.h" #include "qemu/event_notifier.h" #include <libaio.h> @@ -135,6 +136,29 @@ static const AIOCBInfo laio_aiocb_info = { .cancel = laio_cancel, }; +int laio_submit_io_queue(BlockDriverState *bs, void *aio_ctx) +{ + struct qemu_laio_state *s = aio_ctx; + int ret, i; + + while (1) { + ret = io_submit(s->ctx, bs->aio_context->io_queue.idx, + (struct iocb **)bs->aio_context->io_queue.iocbs); + if (ret != -EAGAIN) + break; + } + + if (ret >= 0) + return 0; + + for (i = 0; i < bs->aio_context->io_queue.idx; i++) { + struct qemu_laiocb *laiocb = + container_of(bs->aio_context->io_queue.iocbs[i], struct qemu_laiocb, iocb); + qemu_aio_release(laiocb); + } + return ret; +} + BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque, int type) @@ -168,8 +192,12 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, } io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e)); - if (io_submit(s->ctx, 1, &iocbs) < 0) - goto out_free_aiocb; + if (!bs->aio_context->io_plugged) { + if (io_submit(s->ctx, 1, &iocbs) < 0) + goto out_free_aiocb; + } else { + bdrv_queue_io(bs, iocbs); + } return &laiocb->common; out_free_aiocb: diff --git a/block/raw-aio.h b/block/raw-aio.h index 8cf084e..89fa775 100644 --- a/block/raw-aio.h +++ b/block/raw-aio.h @@ -40,6 +40,7 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, BlockDriverCompletionFunc *cb, void *opaque, int type); void laio_detach_aio_context(void *s, AioContext *old_context); void laio_attach_aio_context(void *s, AioContext *new_context); +int laio_submit_io_queue(BlockDriverState *bs, void *aio_ctx); #endif #ifdef _WIN32 diff --git a/block/raw-posix.c b/block/raw-posix.c index dacf4fb..5869e8e 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1054,6 +1054,17 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs, cb, opaque, type); } +static int raw_aio_submit_io_queue(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + +#ifdef CONFIG_LINUX_AIO + if (s->use_aio) + return laio_submit_io_queue(bs, s->aio_ctx); +#endif + return 0; +} + static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) @@ -1503,6 +1514,7 @@ static BlockDriver bdrv_file = { .bdrv_aio_flush = raw_aio_flush, .bdrv_aio_discard = raw_aio_discard, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_submit_io_queue = raw_aio_submit_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -1902,6 +1914,7 @@ static BlockDriver bdrv_host_device = { .bdrv_aio_flush = raw_aio_flush, .bdrv_aio_discard = hdev_aio_discard, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_submit_io_queue = raw_aio_submit_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2047,6 +2060,7 @@ static BlockDriver bdrv_host_floppy = { .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_submit_io_queue = raw_aio_submit_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2175,6 +2189,7 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_submit_io_queue = raw_aio_submit_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2309,6 +2324,7 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_submit_io_queue = raw_aio_submit_io_queue, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, -- 1.7.9.5