Blame SOURCES/kvm-block-Leave-valid-throttle-timers-when-removing-a-BD.patch

9bac43
From d2461fce36126372a78f020f107389cd72395f15 Mon Sep 17 00:00:00 2001
9bac43
From: Stefan Hajnoczi <stefanha@redhat.com>
9bac43
Date: Fri, 17 Nov 2017 11:19:06 +0100
9bac43
Subject: [PATCH 07/15] block: Leave valid throttle timers when removing a BDS
9bac43
 from a backend
9bac43
9bac43
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
9bac43
Message-id: <20171117111908.8815-8-stefanha@redhat.com>
9bac43
Patchwork-id: 77742
9bac43
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 7/9] block: Leave valid throttle timers when removing a BDS from a backend
9bac43
Bugzilla: 1492295
9bac43
RH-Acked-by: John Snow <jsnow@redhat.com>
9bac43
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
9bac43
RH-Acked-by: Thomas Huth <thuth@redhat.com>
9bac43
9bac43
From: Alberto Garcia <berto@igalia.com>
9bac43
9bac43
If a BlockBackend has I/O limits set then its ThrottleGroupMember
9bac43
structure uses the AioContext from its attached BlockDriverState.
9bac43
Those two contexts must be kept in sync manually. This is not
9bac43
ideal and will be fixed in the future by removing the throttling
9bac43
configuration from the BlockBackend and storing it in an implicit
9bac43
filter node instead, but for now we have to live with this.
9bac43
9bac43
When you remove the BlockDriverState from the backend then the
9bac43
throttle timers are destroyed. If a new BlockDriverState is later
9bac43
inserted then they are created again using the new AioContext.
9bac43
9bac43
There are a couple of problems with this:
9bac43
9bac43
   a) The code manipulates the timers directly, leaving the
9bac43
      ThrottleGroupMember.aio_context field in an inconsisent state.
9bac43
9bac43
   b) If you remove the I/O limits (e.g by destroying the backend)
9bac43
      when the timers are gone then throttle_group_unregister_tgm()
9bac43
      will attempt to destroy them again, crashing QEMU.
9bac43
9bac43
While b) could be fixed easily by allowing the timers to be freed
9bac43
twice, this would result in a situation in which we can no longer
9bac43
guarantee that a valid ThrottleState has a valid AioContext and
9bac43
timers.
9bac43
9bac43
This patch ensures that the timers and AioContext are always valid
9bac43
when I/O limits are set, regardless of whether the BlockBackend has a
9bac43
BlockDriverState inserted or not.
9bac43
9bac43
[Fixed "There'a" typo as suggested by Max Reitz <mreitz@redhat.com>
9bac43
--Stefan]
9bac43
9bac43
Reported-by: sochin jiang <sochin.jiang@huawei.com>
9bac43
Signed-off-by: Alberto Garcia <berto@igalia.com>
9bac43
Reviewed-by: Max Reitz <mreitz@redhat.com>
9bac43
Message-id: e089c66e7c20289b046d782cea4373b765c5bc1d.1510339534.git.berto@igalia.com
9bac43
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9bac43
(cherry picked from commit c89bcf3af01e7a8834cca5344e098bf879e99999)
9bac43
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9bac43
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9bac43
---
9bac43
 block/block-backend.c | 16 ++++++++--------
9bac43
 1 file changed, 8 insertions(+), 8 deletions(-)
9bac43
9bac43
diff --git a/block/block-backend.c b/block/block-backend.c
9bac43
index 0bd439e..083e65f 100644
9bac43
--- a/block/block-backend.c
9bac43
+++ b/block/block-backend.c
9bac43
@@ -655,15 +655,15 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
9bac43
  */
9bac43
 void blk_remove_bs(BlockBackend *blk)
9bac43
 {
9bac43
+    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
9bac43
     BlockDriverState *bs;
9bac43
-    ThrottleTimers *tt;
9bac43
 
9bac43
     notifier_list_notify(&blk->remove_bs_notifiers, blk);
9bac43
-    if (blk->public.throttle_group_member.throttle_state) {
9bac43
-        tt = &blk->public.throttle_group_member.throttle_timers;
9bac43
+    if (tgm->throttle_state) {
9bac43
         bs = blk_bs(blk);
9bac43
         bdrv_drained_begin(bs);
9bac43
-        throttle_timers_detach_aio_context(tt);
9bac43
+        throttle_group_detach_aio_context(tgm);
9bac43
+        throttle_group_attach_aio_context(tgm, qemu_get_aio_context());
9bac43
         bdrv_drained_end(bs);
9bac43
     }
9bac43
 
9bac43
@@ -678,6 +678,7 @@ void blk_remove_bs(BlockBackend *blk)
9bac43
  */
9bac43
 int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
9bac43
 {
9bac43
+    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
9bac43
     blk->root = bdrv_root_attach_child(bs, "root", &child_root,
9bac43
                                        blk->perm, blk->shared_perm, blk, errp);
9bac43
     if (blk->root == NULL) {
9bac43
@@ -686,10 +687,9 @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
9bac43
     bdrv_ref(bs);
9bac43
 
9bac43
     notifier_list_notify(&blk->insert_bs_notifiers, blk);
9bac43
-    if (blk->public.throttle_group_member.throttle_state) {
9bac43
-        throttle_timers_attach_aio_context(
9bac43
-            &blk->public.throttle_group_member.throttle_timers,
9bac43
-            bdrv_get_aio_context(bs));
9bac43
+    if (tgm->throttle_state) {
9bac43
+        throttle_group_detach_aio_context(tgm);
9bac43
+        throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs));
9bac43
     }
9bac43
 
9bac43
     return 0;
9bac43
-- 
9bac43
1.8.3.1
9bac43