Blame SOURCES/kvm-blockdev-Return-bs-to-the-proper-context-on-snapshot.patch

22c213
From 24e5eca4218b294bd013e2d85a38345045506bec Mon Sep 17 00:00:00 2001
22c213
From: Sergio Lopez Pascual <slp@redhat.com>
22c213
Date: Fri, 7 Feb 2020 11:27:48 +0000
22c213
Subject: [PATCH 15/18] blockdev: Return bs to the proper context on snapshot
22c213
 abort
22c213
22c213
RH-Author: Sergio Lopez Pascual <slp@redhat.com>
22c213
Message-id: <20200207112749.25073-9-slp@redhat.com>
22c213
Patchwork-id: 93761
22c213
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 8/9] blockdev: Return bs to the proper context on snapshot abort
22c213
Bugzilla: 1745606 1746217 1773517 1779036 1782111 1782175 1783965
22c213
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
22c213
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
22c213
RH-Acked-by: Max Reitz <mreitz@redhat.com>
22c213
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
22c213
22c213
external_snapshot_abort() calls to bdrv_set_backing_hd(), which
22c213
returns state->old_bs to the main AioContext, as it's intended to be
22c213
used then the BDS is going to be released. As that's not the case when
22c213
aborting an external snapshot, return it to the AioContext it was
22c213
before the call.
22c213
22c213
This issue can be triggered by issuing a transaction with two actions,
22c213
a proper blockdev-snapshot-sync and a bogus one, so the second will
22c213
trigger a transaction abort. This results in a crash with an stack
22c213
trace like this one:
22c213
22c213
 #0  0x00007fa1048b28df in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
22c213
 #1  0x00007fa10489ccf5 in __GI_abort () at abort.c:79
22c213
 #2  0x00007fa10489cbc9 in __assert_fail_base
22c213
     (fmt=0x7fa104a03300 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x5572240b44d8 "bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs)", file=0x557224014d30 "block.c", line=2240, function=<optimized out>) at assert.c:92
22c213
 #3  0x00007fa1048aae96 in __GI___assert_fail
22c213
     (assertion=assertion@entry=0x5572240b44d8 "bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs)", file=file@entry=0x557224014d30 "block.c", line=line@entry=2240, function=function@entry=0x5572240b5d60 <__PRETTY_FUNCTION__.31620> "bdrv_replace_child_noperm") at assert.c:101
22c213
 #4  0x0000557223e631f8 in bdrv_replace_child_noperm (child=0x557225b9c980, new_bs=new_bs@entry=0x557225c42e40) at block.c:2240
22c213
 #5  0x0000557223e68be7 in bdrv_replace_node (from=0x557226951a60, to=0x557225c42e40, errp=0x5572247d6138 <error_abort>) at block.c:4196
22c213
 #6  0x0000557223d069c4 in external_snapshot_abort (common=0x557225d7e170) at blockdev.c:1731
22c213
 #7  0x0000557223d069c4 in external_snapshot_abort (common=0x557225d7e170) at blockdev.c:1717
22c213
 #8  0x0000557223d09013 in qmp_transaction (dev_list=<optimized out>, has_props=<optimized out>, props=0x557225cc7d70, errp=errp@entry=0x7ffe704c0c98) at blockdev.c:2360
22c213
 #9  0x0000557223e32085 in qmp_marshal_transaction (args=<optimized out>, ret=<optimized out>, errp=0x7ffe704c0d08) at qapi/qapi-commands-transaction.c:44
22c213
 #10 0x0000557223ee798c in do_qmp_dispatch (errp=0x7ffe704c0d00, allow_oob=<optimized out>, request=<optimized out>, cmds=0x5572247d3cc0 <qmp_commands>) at qapi/qmp-dispatch.c:132
22c213
 #11 0x0000557223ee798c in qmp_dispatch (cmds=0x5572247d3cc0 <qmp_commands>, request=<optimized out>, allow_oob=<optimized out>) at qapi/qmp-dispatch.c:175
22c213
 #12 0x0000557223e06141 in monitor_qmp_dispatch (mon=0x557225c69ff0, req=<optimized out>) at monitor/qmp.c:120
22c213
 #13 0x0000557223e0678a in monitor_qmp_bh_dispatcher (data=<optimized out>) at monitor/qmp.c:209
22c213
 #14 0x0000557223f2f366 in aio_bh_call (bh=0x557225b9dc60) at util/async.c:117
22c213
 #15 0x0000557223f2f366 in aio_bh_poll (ctx=ctx@entry=0x557225b9c840) at util/async.c:117
22c213
 #16 0x0000557223f32754 in aio_dispatch (ctx=0x557225b9c840) at util/aio-posix.c:459
22c213
 #17 0x0000557223f2f242 in aio_ctx_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at util/async.c:260
22c213
 #18 0x00007fa10913467d in g_main_dispatch (context=0x557225c28e80) at gmain.c:3176
22c213
 #19 0x00007fa10913467d in g_main_context_dispatch (context=context@entry=0x557225c28e80) at gmain.c:3829
22c213
 #20 0x0000557223f31808 in glib_pollfds_poll () at util/main-loop.c:219
22c213
 #21 0x0000557223f31808 in os_host_main_loop_wait (timeout=<optimized out>) at util/main-loop.c:242
22c213
 #22 0x0000557223f31808 in main_loop_wait (nonblocking=<optimized out>) at util/main-loop.c:518
22c213
 #23 0x0000557223d13201 in main_loop () at vl.c:1828
22c213
 #24 0x0000557223bbfb82 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4504
22c213
22c213
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1779036
22c213
Signed-off-by: Sergio Lopez <slp@redhat.com>
22c213
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22c213
(cherry picked from commit 377410f6fb4f6b0d26d4a028c20766fae05de17e)
22c213
Signed-off-by: Sergio Lopez <slp@redhat.com>
22c213
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
22c213
---
22c213
 blockdev.c | 21 +++++++++++++++++++++
22c213
 1 file changed, 21 insertions(+)
22c213
22c213
diff --git a/blockdev.c b/blockdev.c
22c213
index d4ef6cd..4cd9a58 100644
22c213
--- a/blockdev.c
22c213
+++ b/blockdev.c
22c213
@@ -1731,6 +1731,8 @@ static void external_snapshot_abort(BlkActionState *common)
22c213
     if (state->new_bs) {
22c213
         if (state->overlay_appended) {
22c213
             AioContext *aio_context;
22c213
+            AioContext *tmp_context;
22c213
+            int ret;
22c213
 
22c213
             aio_context = bdrv_get_aio_context(state->old_bs);
22c213
             aio_context_acquire(aio_context);
22c213
@@ -1738,6 +1740,25 @@ static void external_snapshot_abort(BlkActionState *common)
22c213
             bdrv_ref(state->old_bs);   /* we can't let bdrv_set_backind_hd()
22c213
                                           close state->old_bs; we need it */
22c213
             bdrv_set_backing_hd(state->new_bs, NULL, &error_abort);
22c213
+
22c213
+            /*
22c213
+             * The call to bdrv_set_backing_hd() above returns state->old_bs to
22c213
+             * the main AioContext. As we're still going to be using it, return
22c213
+             * it to the AioContext it was before.
22c213
+             */
22c213
+            tmp_context = bdrv_get_aio_context(state->old_bs);
22c213
+            if (aio_context != tmp_context) {
22c213
+                aio_context_release(aio_context);
22c213
+                aio_context_acquire(tmp_context);
22c213
+
22c213
+                ret = bdrv_try_set_aio_context(state->old_bs,
22c213
+                                               aio_context, NULL);
22c213
+                assert(ret == 0);
22c213
+
22c213
+                aio_context_release(tmp_context);
22c213
+                aio_context_acquire(aio_context);
22c213
+            }
22c213
+
22c213
             bdrv_replace_node(state->new_bs, state->old_bs, &error_abort);
22c213
             bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */
22c213
 
22c213
-- 
22c213
1.8.3.1
22c213