This patch introduces aio_attach_aio_bs() and its pair for supporting IO submission as batch in AioContext wide, and one typical use case is multi-lun SCSI.
aio_attach_aio_bs() will attach one 'bs' which is capable of IO submission as batch, then all I/O submission in this AioContext will borrow the io queue from this 'bs', so that we can maximum IO submission as batch. aio_detach_aio_bs() will detach the 'bs' when all 'bs' in the AioContext is detached. Signed-off-by: Ming Lei <ming....@canonical.com> --- async.c | 1 + include/block/aio.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/async.c b/async.c index 6e1b282..0f4b530 100644 --- a/async.c +++ b/async.c @@ -305,6 +305,7 @@ AioContext *aio_context_new(Error **errp) event_notifier_test_and_clear); ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD)); ctx->thread_pool = NULL; + ctx->bs_refcnt = 0; qemu_mutex_init(&ctx->bh_lock); rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx); timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx); diff --git a/include/block/aio.h b/include/block/aio.h index 6bf0e04..e34a21f 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -90,6 +90,11 @@ struct AioContext { /* TimerLists for calling timers - one per clock type */ QEMUTimerListGroup tlg; + + /* IO submit as batch in AioContext wide */ + BlockDriverState *master_aio_bs; + int bs_refcnt; + void *opaque; }; /* Used internally to synchronize aio_poll against qemu_bh_schedule. */ @@ -325,4 +330,26 @@ static inline void aio_timer_init(AioContext *ctx, */ int64_t aio_compute_timeout(AioContext *ctx); +static inline bool aio_attach_aio_bs(AioContext *ctx, + BlockDriverState *bs) +{ + if (!ctx->bs_refcnt++) { + ctx->master_aio_bs = bs; + return true; + } + + return false; +} + +static inline bool aio_detach_aio_bs(AioContext *ctx, + BlockDriverState *bs) +{ + if (!--ctx->bs_refcnt) { + ctx->master_aio_bs = NULL; + return true; + } + + return false; +} + #endif -- 1.7.9.5