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