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