aboutsummaryrefslogtreecommitdiff
path: root/qemu-img.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-12-07 16:08:27 +0100
committerKevin Wolf <kwolf@redhat.com>2017-01-09 13:30:13 +0100
commit4baaa8c3d891b57036fd2a7c6a890737793fe3a0 (patch)
tree7f949cc08bcfe8a0ff5a2eff9d4e3203b0c28392 /qemu-img.c
parentffe22bf51065dd33022cf91f77a821d1f11c250d (diff)
qemu-img: fix in-flight count for qemu-img bench
With aio=native (qemu-img bench -n) one or more requests can be completed when a new request is submitted. This in turn can cause bench_cb to recurse before b->in_flight is updated. This causes multiple I/Os to be submitted with the same offset and, furthermore, the blk_aio_* coroutines are never freed and qemu-img aborts. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'qemu-img.c')
-rw-r--r--qemu-img.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/qemu-img.c b/qemu-img.c
index 6949b73ca5..5df66fe661 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3559,20 +3559,23 @@ static void bench_cb(void *opaque, int ret)
}
while (b->n > b->in_flight && b->in_flight < b->nrreq) {
+ int64_t offset = b->offset;
+ /* blk_aio_* might look for completed I/Os and kick bench_cb
+ * again, so make sure this operation is counted by in_flight
+ * and b->offset is ready for the next submission.
+ */
+ b->in_flight++;
+ b->offset += b->step;
+ b->offset %= b->image_size;
if (b->write) {
- acb = blk_aio_pwritev(b->blk, b->offset, b->qiov, 0,
- bench_cb, b);
+ acb = blk_aio_pwritev(b->blk, offset, b->qiov, 0, bench_cb, b);
} else {
- acb = blk_aio_preadv(b->blk, b->offset, b->qiov, 0,
- bench_cb, b);
+ acb = blk_aio_preadv(b->blk, offset, b->qiov, 0, bench_cb, b);
}
if (!acb) {
error_report("Failed to issue request");
exit(EXIT_FAILURE);
}
- b->in_flight++;
- b->offset += b->step;
- b->offset %= b->image_size;
}
}