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

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