diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-12-07 16:08:27 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2017-01-09 13:30:13 +0100 |
commit | 4baaa8c3d891b57036fd2a7c6a890737793fe3a0 (patch) | |
tree | 7f949cc08bcfe8a0ff5a2eff9d4e3203b0c28392 /qemu-img.c | |
parent | ffe22bf51065dd33022cf91f77a821d1f11c250d (diff) | |
download | qemu-4baaa8c3d891b57036fd2a7c6a890737793fe3a0.zip qemu-4baaa8c3d891b57036fd2a7c6a890737793fe3a0.tar.gz qemu-4baaa8c3d891b57036fd2a7c6a890737793fe3a0.tar.bz2 |
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.c | 17 |
1 files changed, 10 insertions, 7 deletions
@@ -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; } } |