* [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch @ 2014-07-01 16:35 Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 1/4] block: block: introduce bdrv_io_plug() and bdrv_io_unplug() Ming Lei ` (4 more replies) 0 siblings, 5 replies; 7+ messages in thread From: Ming Lei @ 2014-07-01 16:35 UTC (permalink / raw) To: Peter Maydell, qemu-devel, Paolo Bonzini, Stefan Hajnoczi Cc: Kevin Wolf, Fam Zheng, Michael S. Tsirkin Hi, The commit 580b6b2aa2(dataplane: use the QEMU block layer for I/O) introduces ~40% throughput regression on virtio-blk dataplane, and one of causes is that submitting I/O at batch is removed. This patchset trys to introduce this mechanism on block, at least, linux-aio can benefit from that. With these patches, it is observed that thoughout on virtio-blk dataplane can be improved a lot, see data in commit log of patch 3/3. It should be possible to apply the batch mechanism to other devices (such as virtio-scsi) too. V3: - only support submitting I/O at batch for raw format, pointed by Kevin V2: - define return value of bdrv_io_unplug as void, suggested by Paolo - avoid busy-wait for handling io_submit V1: - move queuing io stuff into linux-aio.c as suggested by Paolo Thanks, -- Ming Lei ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v3 1/4] block: block: introduce bdrv_io_plug() and bdrv_io_unplug() 2014-07-01 16:35 [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch Ming Lei @ 2014-07-01 16:35 ` Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 2/4] block/raw_bsd.c: support io plug and unplug for raw format image Ming Lei ` (3 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Ming Lei @ 2014-07-01 16:35 UTC (permalink / raw) To: Peter Maydell, qemu-devel, Paolo Bonzini, Stefan Hajnoczi Cc: Kevin Wolf, Ming Lei, Fam Zheng, Michael S. Tsirkin This patch introduces these two APIs so that following patches can support queuing I/O requests and submitting them at batch for improving I/O performance. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Ming Lei <ming.lei@canonical.com> --- block.c | 17 +++++++++++++++++ include/block/block.h | 3 +++ include/block/block_int.h | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/block.c b/block.c index 217f523..6245303 100644 --- a/block.c +++ b/block.c @@ -1910,6 +1910,7 @@ void bdrv_drain_all(void) bool bs_busy; aio_context_acquire(aio_context); + bdrv_io_unplug(bs); bdrv_start_throttled_reqs(bs); bs_busy = bdrv_requests_pending(bs); bs_busy |= aio_poll(aio_context, bs_busy); @@ -5774,3 +5775,19 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate) return false; } + +void bdrv_io_plug(BlockDriverState *bs) +{ + BlockDriver *drv = bs->drv; + if (drv && drv->bdrv_io_plug) { + drv->bdrv_io_plug(bs); + } +} + +void bdrv_io_unplug(BlockDriverState *bs) +{ + BlockDriver *drv = bs->drv; + if (drv && drv->bdrv_io_unplug) { + drv->bdrv_io_unplug(bs); + } +} diff --git a/include/block/block.h b/include/block/block.h index d0baf4f..ea627d2 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -578,4 +578,7 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs); */ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context); +void bdrv_io_plug(BlockDriverState *bs); +void bdrv_io_unplug(BlockDriverState *bs); + #endif diff --git a/include/block/block_int.h b/include/block/block_int.h index 715c761..0d75ca6 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -257,6 +257,10 @@ struct BlockDriver { void (*bdrv_attach_aio_context)(BlockDriverState *bs, AioContext *new_context); + /* io queue for linux-aio */ + void (*bdrv_io_plug)(BlockDriverState *bs); + void (*bdrv_io_unplug)(BlockDriverState *bs); + QLIST_ENTRY(BlockDriver) list; }; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v3 2/4] block/raw_bsd.c: support io plug and unplug for raw format image 2014-07-01 16:35 [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 1/4] block: block: introduce bdrv_io_plug() and bdrv_io_unplug() Ming Lei @ 2014-07-01 16:35 ` Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 3/4] linux-aio: implement io plug and unplug Ming Lei ` (2 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Ming Lei @ 2014-07-01 16:35 UTC (permalink / raw) To: Peter Maydell, qemu-devel, Paolo Bonzini, Stefan Hajnoczi Cc: Kevin Wolf, Ming Lei, Fam Zheng, Michael S. Tsirkin This patch defines .bdrv_io_plug and .bdrv_io_unplug callbacks, so that we can support to submit IO at batch for linux-aio. Signed-off-by: Ming Lei <ming.lei@canonical.com> --- block/raw_bsd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 492f58d..933822b 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -174,6 +174,16 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename) return 1; } +static void raw_io_plug(BlockDriverState *bs) +{ + bdrv_io_plug(bs->file); +} + +static void raw_io_unplug(BlockDriverState *bs) +{ + bdrv_io_unplug(bs->file); +} + static BlockDriver bdrv_raw = { .format_name = "raw", .bdrv_probe = &raw_probe, @@ -198,7 +208,9 @@ static BlockDriver bdrv_raw = { .bdrv_ioctl = &raw_ioctl, .bdrv_aio_ioctl = &raw_aio_ioctl, .create_opts = &raw_create_opts, - .bdrv_has_zero_init = &raw_has_zero_init + .bdrv_has_zero_init = &raw_has_zero_init, + .bdrv_io_plug = &raw_io_plug, + .bdrv_io_unplug = &raw_io_unplug }; static void bdrv_raw_init(void) -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v3 3/4] linux-aio: implement io plug and unplug 2014-07-01 16:35 [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 1/4] block: block: introduce bdrv_io_plug() and bdrv_io_unplug() Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 2/4] block/raw_bsd.c: support io plug and unplug for raw format image Ming Lei @ 2014-07-01 16:35 ` Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 4/4] dataplane: submit I/O at batch Ming Lei 2014-07-01 17:06 ` [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce " Paolo Bonzini 4 siblings, 0 replies; 7+ messages in thread From: Ming Lei @ 2014-07-01 16:35 UTC (permalink / raw) To: Peter Maydell, qemu-devel, Paolo Bonzini, Stefan Hajnoczi Cc: Kevin Wolf, Ming Lei, Fam Zheng, Michael S. Tsirkin This patch implements .bdrv_io_plug and .bdrv_io_unplug callbacks for linux-aio Block Drivers, so that submitting I/O at batch can be supported on linux-aio. Signed-off-by: Ming Lei <ming.lei@canonical.com> --- block/linux-aio.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++-- block/raw-aio.h | 2 ++ block/raw-posix.c | 30 +++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) diff --git a/block/linux-aio.c b/block/linux-aio.c index f0a2c08..195f0e3 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -25,6 +25,8 @@ */ #define MAX_EVENTS 128 +#define MAX_QUEUED_IO 128 + struct qemu_laiocb { BlockDriverAIOCB common; struct qemu_laio_state *ctx; @@ -36,9 +38,19 @@ struct qemu_laiocb { QLIST_ENTRY(qemu_laiocb) node; }; +struct laio_queue { + struct iocb *iocbs[MAX_QUEUED_IO]; + bool plugged; + unsigned int size; + unsigned int idx; +}; + struct qemu_laio_state { io_context_t ctx; EventNotifier e; + + /* io queue for submit at batch */ + struct laio_queue io_q; }; static inline ssize_t io_event_ret(struct io_event *ev) @@ -135,6 +147,70 @@ static const AIOCBInfo laio_aiocb_info = { .cancel = laio_cancel, }; +static void ioq_init(struct laio_queue *io_q) +{ + io_q->size = MAX_QUEUED_IO; + io_q->idx = 0; + io_q->plugged = false; +} + +static int ioq_submit(struct qemu_laio_state *s) +{ + int ret, i = 0; + int len = s->io_q.idx; + + do { + ret = io_submit(s->ctx, len, s->io_q.iocbs); + } while (i++ < 3 && ret == -EAGAIN); + + /* empty io queue */ + s->io_q.idx = 0; + + if (ret >= 0) + return 0; + + for (i = 0; i < len; i++) { + struct qemu_laiocb *laiocb = + container_of(s->io_q.iocbs[i], struct qemu_laiocb, iocb); + + laiocb->ret = ret; + qemu_laio_process_completion(s, laiocb); + } + return ret; +} + +static void ioq_enqueue(struct qemu_laio_state *s, struct iocb *iocb) +{ + unsigned int idx = s->io_q.idx; + + s->io_q.iocbs[idx++] = iocb; + s->io_q.idx = idx; + + /* submit immediately if queue is full */ + if (idx == s->io_q.size) + ioq_submit(s); +} + +void laio_io_plug(BlockDriverState *bs, void *aio_ctx) +{ + struct qemu_laio_state *s = aio_ctx; + + s->io_q.plugged = true; +} + +int laio_io_unplug(BlockDriverState *bs, void *aio_ctx) +{ + struct qemu_laio_state *s = aio_ctx; + int ret = 0; + + if (s->io_q.idx > 0) { + ret = ioq_submit(s); + } + s->io_q.plugged = false; + + 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 +244,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 (!s->io_q.plugged) { + if (io_submit(s->ctx, 1, &iocbs) < 0) + goto out_free_aiocb; + } else { + ioq_enqueue(s, iocbs); + } return &laiocb->common; out_free_aiocb: @@ -204,6 +284,8 @@ void *laio_init(void) goto out_close_efd; } + ioq_init(&s->io_q); + return s; out_close_efd: diff --git a/block/raw-aio.h b/block/raw-aio.h index 8cf084e..ed47c3d 100644 --- a/block/raw-aio.h +++ b/block/raw-aio.h @@ -40,6 +40,8 @@ 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); +void laio_io_plug(BlockDriverState *bs, void *aio_ctx); +int laio_io_unplug(BlockDriverState *bs, void *aio_ctx); #endif #ifdef _WIN32 diff --git a/block/raw-posix.c b/block/raw-posix.c index dacf4fb..ce548e1 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1054,6 +1054,26 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs, cb, opaque, type); } +static void raw_aio_plug(BlockDriverState *bs) +{ +#ifdef CONFIG_LINUX_AIO + BDRVRawState *s = bs->opaque; + if (s->use_aio) { + laio_io_plug(bs, s->aio_ctx); + } +#endif +} + +static void raw_aio_unplug(BlockDriverState *bs) +{ +#ifdef CONFIG_LINUX_AIO + BDRVRawState *s = bs->opaque; + if (s->use_aio) { + laio_io_unplug(bs, s->aio_ctx); + } +#endif +} + static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) @@ -1503,6 +1523,8 @@ static BlockDriver bdrv_file = { .bdrv_aio_flush = raw_aio_flush, .bdrv_aio_discard = raw_aio_discard, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -1902,6 +1924,8 @@ static BlockDriver bdrv_host_device = { .bdrv_aio_flush = raw_aio_flush, .bdrv_aio_discard = hdev_aio_discard, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2047,6 +2071,8 @@ static BlockDriver bdrv_host_floppy = { .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2175,6 +2201,8 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, @@ -2309,6 +2337,8 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v3 4/4] dataplane: submit I/O at batch 2014-07-01 16:35 [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch Ming Lei ` (2 preceding siblings ...) 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 3/4] linux-aio: implement io plug and unplug Ming Lei @ 2014-07-01 16:35 ` Ming Lei 2014-07-01 17:15 ` Eric Blake 2014-07-01 17:06 ` [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce " Paolo Bonzini 4 siblings, 1 reply; 7+ messages in thread From: Ming Lei @ 2014-07-01 16:35 UTC (permalink / raw) To: Peter Maydell, qemu-devel, Paolo Bonzini, Stefan Hajnoczi Cc: Kevin Wolf, Ming Lei, Fam Zheng, Michael S. Tsirkin Before commit 580b6b2aa2(dataplane: use the Qemu block layer for I/O), dataplane for virtio-blk submits block I/O at batch. This commit 580b6b2aa2 replaces the custom linux AIO implementation(including I/O batch) with Qemu block layer, but this commit causes ~40% throughput regression on virtio-blk performance, and removing submitting I/O at batch is one of the cause. This patch applys the new introduced bdrv_io_plug() and bdrv_io_unplug() interfaces to support submitting I/O at batch for Qemu block layer, and in my test, the change can improve thoughput by ~30% with 'aio=native'. Following my fio test script: [global] direct=1 size=4G bsrange=4k-4k timeout=40 numjobs=4 ioengine=libaio iodepth=64 filename=/dev/vdc group_reporting=1 [f] rw=randread Result on one of my small machine(host: x86_64, 2cores, 4thread, guest: 4cores): - qemu master: 59K IOPS - qemu master with these patches: 81K IOPS - 2.0.0 release(dataplane using custom linux aio): 104K IOPS Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Ming Lei <ming.lei@canonical.com> --- hw/block/dataplane/virtio-blk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index c10b7b7..8fefcce 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -289,6 +289,7 @@ static void handle_notify(EventNotifier *e) int ret; event_notifier_test_and_clear(&s->host_notifier); + bdrv_io_plug(s->blk->conf.bs); for (;;) { /* Disable guest->host notifies to avoid unnecessary vmexits */ vring_disable_notification(s->vdev, &s->vring); @@ -322,6 +323,7 @@ static void handle_notify(EventNotifier *e) break; } } + bdrv_io_unplug(s->blk->conf.bs); } /* Context: QEMU global mutex held */ -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/4] dataplane: submit I/O at batch 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 4/4] dataplane: submit I/O at batch Ming Lei @ 2014-07-01 17:15 ` Eric Blake 0 siblings, 0 replies; 7+ messages in thread From: Eric Blake @ 2014-07-01 17:15 UTC (permalink / raw) To: Ming Lei, Peter Maydell, qemu-devel, Paolo Bonzini, Stefan Hajnoczi Cc: Kevin Wolf, Fam Zheng, Michael S. Tsirkin [-- Attachment #1: Type: text/plain, Size: 913 bytes --] On 07/01/2014 10:35 AM, Ming Lei wrote: > Before commit 580b6b2aa2(dataplane: use the Qemu block > layer for I/O), dataplane for virtio-blk submits block > I/O at batch. s/at/as a/ > > This commit 580b6b2aa2 replaces the custom linux AIO > implementation(including I/O batch) with Qemu block s/(/ (/ > layer, but this commit causes ~40% throughput regression > on virtio-blk performance, and removing submitting I/O > at batch is one of the cause. s/at/as a/ > > This patch applys the new introduced bdrv_io_plug() and s/applys/applies/ s/new/newly/ > bdrv_io_unplug() interfaces to support submitting I/O > at batch for Qemu block layer, and in my test, the change s/at/as a/ > can improve thoughput by ~30% with 'aio=native'. s/thoughput/throughput/ -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 604 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch 2014-07-01 16:35 [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch Ming Lei ` (3 preceding siblings ...) 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 4/4] dataplane: submit I/O at batch Ming Lei @ 2014-07-01 17:06 ` Paolo Bonzini 4 siblings, 0 replies; 7+ messages in thread From: Paolo Bonzini @ 2014-07-01 17:06 UTC (permalink / raw) To: Ming Lei, Peter Maydell, qemu-devel, Stefan Hajnoczi Cc: Kevin Wolf, Fam Zheng, Michael S. Tsirkin Il 01/07/2014 18:35, Ming Lei ha scritto: > Hi, > > The commit 580b6b2aa2(dataplane: use the QEMU block layer for I/O) > introduces ~40% throughput regression on virtio-blk dataplane, and > one of causes is that submitting I/O at batch is removed. > > This patchset trys to introduce this mechanism on block, at least, > linux-aio can benefit from that. > > With these patches, it is observed that thoughout on virtio-blk > dataplane can be improved a lot, see data in commit log of patch > 3/3. > > It should be possible to apply the batch mechanism to other devices > (such as virtio-scsi) too. > > V3: > - only support submitting I/O at batch for raw format, pointed by > Kevin As I commented in the review, I would like evidence that this is necessary. It should work for all formats IMO. Paolo ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-07-01 17:16 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-07-01 16:35 [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce submit I/O at batch Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 1/4] block: block: introduce bdrv_io_plug() and bdrv_io_unplug() Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 2/4] block/raw_bsd.c: support io plug and unplug for raw format image Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 3/4] linux-aio: implement io plug and unplug Ming Lei 2014-07-01 16:35 ` [Qemu-devel] [PATCH v3 4/4] dataplane: submit I/O at batch Ming Lei 2014-07-01 17:15 ` Eric Blake 2014-07-01 17:06 ` [Qemu-devel] [PATCH v3 0/3] linux-aio: introduce " Paolo Bonzini
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).