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