yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-block-backend-Decrease-in_flight-only-after-callback.patch

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