diff options
author | Kevin Wolf <kwolf@redhat.com> | 2018-09-06 17:47:22 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2018-09-25 15:50:15 +0200 |
commit | 46aaf2a566e364a62315219255099cbf1c9b990d (patch) | |
tree | eabe645e414520fad60cfbc13a9e512c1db27fdd /block/block-backend.c | |
parent | 5ca9d21bd1c8eeb578d0964e31bd03d47c25773d (diff) |
block-backend: Decrease in_flight only after callback
Request callbacks can do pretty much anything, including operations that
will yield from the coroutine (such as draining the backend). In that
case, a decreased in_flight would be visible to other code and could
lead to a drain completing while the callback hasn't actually completed
yet.
Note that reordering these operations forbids calling drain directly
inside an AIO callback. As Paolo explains, indirectly calling it is
okay:
- Calling it through a coroutine is okay, because then
bdrv_drained_begin() goes through bdrv_co_yield_to_drain() and you
have in_flight=2 when bdrv_co_yield_to_drain() yields, then soon
in_flight=1 when the aio_co_wake() in the AIO callback completes, then
in_flight=0 after the bottom half starts.
- Calling it through a bottom half would be okay too, as long as the AIO
callback remembers to do inc_in_flight/dec_in_flight just like
bdrv_co_yield_to_drain() and bdrv_co_drain_bh_cb() do
A few more important cases that come to mind:
- A coroutine that yields because of I/O is okay, with a sequence
similar to bdrv_co_yield_to_drain().
- A coroutine that yields with no I/O pending will correctly decrease
in_flight to zero before yielding.
- Calling more AIO from the callback won't overflow the counter just
because of mutual recursion, because AIO functions always yield at
least once before invoking the callback.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'block/block-backend.c')
-rw-r--r-- | block/block-backend.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/block/block-backend.c b/block/block-backend.c index f71fdb4315..551e4e1708 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1339,8 +1339,8 @@ static const AIOCBInfo blk_aio_em_aiocb_info = { static void blk_aio_complete(BlkAioEmAIOCB *acb) { if (acb->has_returned) { - blk_dec_in_flight(acb->rwco.blk); acb->common.cb(acb->common.opaque, acb->rwco.ret); + blk_dec_in_flight(acb->rwco.blk); qemu_aio_unref(acb); } } |