26ba25
From 27fd652033779a16561160bef8aeda7f8f9c04be Mon Sep 17 00:00:00 2001
26ba25
From: Kevin Wolf <kwolf@redhat.com>
26ba25
Date: Wed, 10 Oct 2018 20:22:05 +0100
26ba25
Subject: [PATCH 39/49] block-backend: Decrease in_flight only after callback
26ba25
26ba25
RH-Author: Kevin Wolf <kwolf@redhat.com>
26ba25
Message-id: <20181010202213.7372-27-kwolf@redhat.com>
26ba25
Patchwork-id: 82617
26ba25
O-Subject: [RHEL-8 qemu-kvm PATCH 36/44] block-backend: Decrease in_flight only after callback
26ba25
Bugzilla: 1637976
26ba25
RH-Acked-by: Max Reitz <mreitz@redhat.com>
26ba25
RH-Acked-by: John Snow <jsnow@redhat.com>
26ba25
RH-Acked-by: Thomas Huth <thuth@redhat.com>
26ba25
26ba25
Request callbacks can do pretty much anything, including operations that
26ba25
will yield from the coroutine (such as draining the backend). In that
26ba25
case, a decreased in_flight would be visible to other code and could
26ba25
lead to a drain completing while the callback hasn't actually completed
26ba25
yet.
26ba25
26ba25
Note that reordering these operations forbids calling drain directly
26ba25
inside an AIO callback. As Paolo explains, indirectly calling it is
26ba25
okay:
26ba25
26ba25
- Calling it through a coroutine is okay, because then
26ba25
  bdrv_drained_begin() goes through bdrv_co_yield_to_drain() and you
26ba25
  have in_flight=2 when bdrv_co_yield_to_drain() yields, then soon
26ba25
  in_flight=1 when the aio_co_wake() in the AIO callback completes, then
26ba25
  in_flight=0 after the bottom half starts.
26ba25
26ba25
- Calling it through a bottom half would be okay too, as long as the AIO
26ba25
  callback remembers to do inc_in_flight/dec_in_flight just like
26ba25
  bdrv_co_yield_to_drain() and bdrv_co_drain_bh_cb() do
26ba25
26ba25
A few more important cases that come to mind:
26ba25
26ba25
- A coroutine that yields because of I/O is okay, with a sequence
26ba25
  similar to bdrv_co_yield_to_drain().
26ba25
26ba25
- A coroutine that yields with no I/O pending will correctly decrease
26ba25
  in_flight to zero before yielding.
26ba25
26ba25
- Calling more AIO from the callback won't overflow the counter just
26ba25
  because of mutual recursion, because AIO functions always yield at
26ba25
  least once before invoking the callback.
26ba25
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Reviewed-by: Fam Zheng <famz@redhat.com>
26ba25
Reviewed-by: Max Reitz <mreitz@redhat.com>
26ba25
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
26ba25
(cherry picked from commit 46aaf2a566e364a62315219255099cbf1c9b990d)
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 block/block-backend.c | 2 +-
26ba25
 1 file changed, 1 insertion(+), 1 deletion(-)
26ba25
26ba25
diff --git a/block/block-backend.c b/block/block-backend.c
26ba25
index bfd0331..b8ea286 100644
26ba25
--- a/block/block-backend.c
26ba25
+++ b/block/block-backend.c
26ba25
@@ -1341,8 +1341,8 @@ static const AIOCBInfo blk_aio_em_aiocb_info = {
26ba25
 static void blk_aio_complete(BlkAioEmAIOCB *acb)
26ba25
 {
26ba25
     if (acb->has_returned) {
26ba25
-        blk_dec_in_flight(acb->rwco.blk);
26ba25
         acb->common.cb(acb->common.opaque, acb->rwco.ret);
26ba25
+        blk_dec_in_flight(acb->rwco.blk);
26ba25
         qemu_aio_unref(acb);
26ba25
     }
26ba25
 }
26ba25
-- 
26ba25
1.8.3.1
26ba25