yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

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

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