cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-blockdev-Acquire-AioContext-on-dirty-bitmap-function.patch

902636
From dc2654f2319ad6c379e0ba10be143726c6f0e9e0 Mon Sep 17 00:00:00 2001
902636
From: Sergio Lopez Pascual <slp@redhat.com>
902636
Date: Fri, 7 Feb 2020 11:27:47 +0000
902636
Subject: [PATCH 14/18] blockdev: Acquire AioContext on dirty bitmap functions
902636
902636
RH-Author: Sergio Lopez Pascual <slp@redhat.com>
902636
Message-id: <20200207112749.25073-8-slp@redhat.com>
902636
Patchwork-id: 93760
902636
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 7/9] blockdev: Acquire AioContext on dirty bitmap functions
902636
Bugzilla: 1745606 1746217 1773517 1779036 1782111 1782175 1783965
902636
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
902636
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
902636
RH-Acked-by: Max Reitz <mreitz@redhat.com>
902636
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
902636
902636
Dirty map addition and removal functions are not acquiring to BDS
902636
AioContext, while they may call to code that expects it to be
902636
acquired.
902636
902636
This may trigger a crash with a stack trace like this one:
902636
902636
 #0  0x00007f0ef146370f in __GI_raise (sig=sig@entry=6)
902636
     at ../sysdeps/unix/sysv/linux/raise.c:50
902636
 #1  0x00007f0ef144db25 in __GI_abort () at abort.c:79
902636
 #2  0x0000565022294dce in error_exit
902636
     (err=<optimized out>, msg=msg@entry=0x56502243a730 <__func__.16350> "qemu_mutex_unlock_impl") at util/qemu-thread-posix.c:36
902636
 #3  0x00005650222950ba in qemu_mutex_unlock_impl
902636
     (mutex=mutex@entry=0x5650244b0240, file=file@entry=0x565022439adf "util/async.c", line=line@entry=526) at util/qemu-thread-posix.c:108
902636
 #4  0x0000565022290029 in aio_context_release
902636
     (ctx=ctx@entry=0x5650244b01e0) at util/async.c:526
902636
 #5  0x000056502221cd08 in bdrv_can_store_new_dirty_bitmap
902636
     (bs=bs@entry=0x5650244dc820, name=name@entry=0x56502481d360 "bitmap1", granularity=granularity@entry=65536, errp=errp@entry=0x7fff22831718)
902636
     at block/dirty-bitmap.c:542
902636
 #6  0x000056502206ae53 in qmp_block_dirty_bitmap_add
902636
     (errp=0x7fff22831718, disabled=false, has_disabled=<optimized out>, persistent=<optimized out>, has_persistent=true, granularity=65536, has_granularity=<optimized out>, name=0x56502481d360 "bitmap1", node=<optimized out>) at blockdev.c:2894
902636
 #7  0x000056502206ae53 in qmp_block_dirty_bitmap_add
902636
     (node=<optimized out>, name=0x56502481d360 "bitmap1", has_granularity=<optimized out>, granularity=<optimized out>, has_persistent=true, persistent=<optimized out>, has_disabled=false, disabled=false, errp=0x7fff22831718) at blockdev.c:2856
902636
 #8  0x00005650221847a3 in qmp_marshal_block_dirty_bitmap_add
902636
     (args=<optimized out>, ret=<optimized out>, errp=0x7fff22831798)
902636
     at qapi/qapi-commands-block-core.c:651
902636
 #9  0x0000565022247e6c in do_qmp_dispatch
902636
     (errp=0x7fff22831790, allow_oob=<optimized out>, request=<optimized out>, cmds=0x565022b32d60 <qmp_commands>) at qapi/qmp-dispatch.c:132
902636
 #10 0x0000565022247e6c in qmp_dispatch
902636
     (cmds=0x565022b32d60 <qmp_commands>, request=<optimized out>, allow_oob=<optimized out>) at qapi/qmp-dispatch.c:175
902636
 #11 0x0000565022166061 in monitor_qmp_dispatch
902636
     (mon=0x56502450faa0, req=<optimized out>) at monitor/qmp.c:145
902636
 #12 0x00005650221666fa in monitor_qmp_bh_dispatcher
902636
     (data=<optimized out>) at monitor/qmp.c:234
902636
 #13 0x000056502228f866 in aio_bh_call (bh=0x56502440eae0)
902636
     at util/async.c:117
902636
 #14 0x000056502228f866 in aio_bh_poll (ctx=ctx@entry=0x56502440d7a0)
902636
     at util/async.c:117
902636
 #15 0x0000565022292c54 in aio_dispatch (ctx=0x56502440d7a0)
902636
     at util/aio-posix.c:459
902636
 #16 0x000056502228f742 in aio_ctx_dispatch
902636
     (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at util/async.c:260
902636
 #17 0x00007f0ef5ce667d in g_main_dispatch (context=0x56502449aa40)
902636
     at gmain.c:3176
902636
 #18 0x00007f0ef5ce667d in g_main_context_dispatch
902636
     (context=context@entry=0x56502449aa40) at gmain.c:3829
902636
 #19 0x0000565022291d08 in glib_pollfds_poll () at util/main-loop.c:219
902636
 #20 0x0000565022291d08 in os_host_main_loop_wait
902636
     (timeout=<optimized out>) at util/main-loop.c:242
902636
 #21 0x0000565022291d08 in main_loop_wait (nonblocking=<optimized out>)
902636
     at util/main-loop.c:518
902636
 #22 0x00005650220743c1 in main_loop () at vl.c:1828
902636
 #23 0x0000565021f20a72 in main
902636
     (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>)
902636
     at vl.c:4504
902636
902636
Fix this by acquiring the AioContext at qmp_block_dirty_bitmap_add()
902636
and qmp_block_dirty_bitmap_add().
902636
902636
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1782175
902636
Signed-off-by: Sergio Lopez <slp@redhat.com>
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
(cherry picked from commit 91005a495e228ebd7e5e173cd18f952450eef82d)
902636
Signed-off-by: Sergio Lopez <slp@redhat.com>
902636
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
902636
---
902636
 blockdev.c | 22 ++++++++++++++++++----
902636
 1 file changed, 18 insertions(+), 4 deletions(-)
902636
902636
diff --git a/blockdev.c b/blockdev.c
902636
index 1dacbc2..d4ef6cd 100644
902636
--- a/blockdev.c
902636
+++ b/blockdev.c
902636
@@ -2984,6 +2984,7 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
902636
 {
902636
     BlockDriverState *bs;
902636
     BdrvDirtyBitmap *bitmap;
902636
+    AioContext *aio_context;
902636
 
902636
     if (!name || name[0] == '\0') {
902636
         error_setg(errp, "Bitmap name cannot be empty");
902636
@@ -2995,11 +2996,14 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
902636
         return;
902636
     }
902636
 
902636
+    aio_context = bdrv_get_aio_context(bs);
902636
+    aio_context_acquire(aio_context);
902636
+
902636
     if (has_granularity) {
902636
         if (granularity < 512 || !is_power_of_2(granularity)) {
902636
             error_setg(errp, "Granularity must be power of 2 "
902636
                              "and at least 512");
902636
-            return;
902636
+            goto out;
902636
         }
902636
     } else {
902636
         /* Default to cluster size, if available: */
902636
@@ -3017,12 +3021,12 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
902636
     if (persistent &&
902636
         !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
902636
     {
902636
-        return;
902636
+        goto out;
902636
     }
902636
 
902636
     bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
902636
     if (bitmap == NULL) {
902636
-        return;
902636
+        goto out;
902636
     }
902636
 
902636
     if (disabled) {
902636
@@ -3030,6 +3034,9 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
902636
     }
902636
 
902636
     bdrv_dirty_bitmap_set_persistence(bitmap, persistent);
902636
+
902636
+out:
902636
+    aio_context_release(aio_context);
902636
 }
902636
 
902636
 static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
902636
@@ -3038,21 +3045,27 @@ static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
902636
 {
902636
     BlockDriverState *bs;
902636
     BdrvDirtyBitmap *bitmap;
902636
+    AioContext *aio_context;
902636
 
902636
     bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
902636
     if (!bitmap || !bs) {
902636
         return NULL;
902636
     }
902636
 
902636
+    aio_context = bdrv_get_aio_context(bs);
902636
+    aio_context_acquire(aio_context);
902636
+
902636
     if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO,
902636
                                 errp)) {
902636
+        aio_context_release(aio_context);
902636
         return NULL;
902636
     }
902636
 
902636
     if (bdrv_dirty_bitmap_get_persistence(bitmap) &&
902636
         bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0)
902636
     {
902636
-            return NULL;
902636
+        aio_context_release(aio_context);
902636
+        return NULL;
902636
     }
902636
 
902636
     if (release) {
902636
@@ -3063,6 +3076,7 @@ static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
902636
         *bitmap_bs = bs;
902636
     }
902636
 
902636
+    aio_context_release(aio_context);
902636
     return release ? NULL : bitmap;
902636
 }
902636
 
902636
-- 
902636
1.8.3.1
902636