diff options
author | Tim Smith <tim.smith@citrix.com> | 2018-12-12 11:16:24 +0000 |
---|---|---|
committer | Anthony PERARD <anthony.perard@citrix.com> | 2019-01-14 13:45:40 +0000 |
commit | 6de45f91096da4d5e91f72a21bdfc86e7b506b67 (patch) | |
tree | fea0ecb0771a13851c064a6132cf829737a1c8fa /hw | |
parent | 1077bcaccd6596ce6ccc67eee8b2c1bab112fa68 (diff) | |
download | qemu-6de45f91096da4d5e91f72a21bdfc86e7b506b67.zip qemu-6de45f91096da4d5e91f72a21bdfc86e7b506b67.tar.gz qemu-6de45f91096da4d5e91f72a21bdfc86e7b506b67.tar.bz2 |
xen-block: improve batching behaviour
When I/O consists of many small requests, performance is improved by
batching them together in a single io_submit() call. When there are
relatively few requests, the extra overhead is not worth it. This
introduces a check to start batching I/O requests via blk_io_plug()/
blk_io_unplug() in an amount proportional to the number which were
already in flight at the time we started reading the ring.
Signed-off-by: Tim Smith <tim.smith@citrix.com>
Re-based and commit comment adjusted.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/dataplane/xen-block.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c index 8e3965e..acd23a7 100644 --- a/hw/block/dataplane/xen-block.c +++ b/hw/block/dataplane/xen-block.c @@ -528,10 +528,18 @@ static int xen_block_get_request(XenBlockDataPlane *dataplane, return 0; } +/* + * Threshold of in-flight requests above which we will start using + * blk_io_plug()/blk_io_unplug() to batch requests. + */ +#define IO_PLUG_THRESHOLD 1 + static void xen_block_handle_requests(XenBlockDataPlane *dataplane) { RING_IDX rc, rp; XenBlockRequest *request; + int inflight_atstart = dataplane->requests_inflight; + int batched = 0; dataplane->more_work = 0; @@ -540,6 +548,18 @@ static void xen_block_handle_requests(XenBlockDataPlane *dataplane) xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ xen_block_send_response_all(dataplane); + /* + * If there was more than IO_PLUG_THRESHOLD requests in flight + * when we got here, this is an indication that there the bottleneck + * is below us, so it's worth beginning to batch up I/O requests + * rather than submitting them immediately. The maximum number + * of requests we're willing to batch is the number already in + * flight, so it can grow up to max_requests when the bottleneck + * is below us. + */ + if (inflight_atstart > IO_PLUG_THRESHOLD) { + blk_io_plug(dataplane->blk); + } while (rc != rp) { /* pull request from ring */ if (RING_REQUEST_CONS_OVERFLOW(&dataplane->rings.common, rc)) { @@ -585,7 +605,22 @@ static void xen_block_handle_requests(XenBlockDataPlane *dataplane) continue; } + if (inflight_atstart > IO_PLUG_THRESHOLD && + batched >= inflight_atstart) { + blk_io_unplug(dataplane->blk); + } xen_block_do_aio(request); + if (inflight_atstart > IO_PLUG_THRESHOLD) { + if (batched >= inflight_atstart) { + blk_io_plug(dataplane->blk); + batched = 0; + } else { + batched++; + } + } + } + if (inflight_atstart > IO_PLUG_THRESHOLD) { + blk_io_unplug(dataplane->blk); } if (dataplane->more_work && |