qemu coredump:
  0x00007f9e7205c81b in raise () from /usr/lib64/libc.so.6
  0x00007f9e7205db41 in abort () from /usr/lib64/libc.so.6
  0x00007f9e71ddbe94 in error_exit (err=<optimized out>, 
msg=msg@entry=0x7f9e71ec1b50 <__func__.20287> "qemu_mutex_unlock_impl")
    at /usr/src/debug/qemu-4.1.0-170.x86_64/util/qemu-thread-posix.c:36
  0x00007f9e71ddc61f in qemu_mutex_unlock_impl 
(mutex=mutex@entry=0x5559850b0b90, file=file@entry=0x7f9e71ec0978 
"/home/abuild/rpmbuild/BUILD/qemu-4.1.0/util/async.c",
    line=line@entry=524) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/util/qemu-thread-posix.c:108
  0x00007f9e71dd5bb5 in aio_context_release (ctx=ctx@entry=0x5559850b0b30) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/util/async.c:524
  0x00007f9e70dfed28 in bdrv_flush (bs=bs@entry=0x5559851f0a20) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/block/io.c:2778
  0x00007f9e70e37f63 in bdrv_close (bs=bs@entry=0x5559851f0a20) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/block.c:4025
  0x00007f9e70e38193 in bdrv_delete (bs=0x5559851f0a20) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/block.c:4271
  0x00007f9e70e38225 in bdrv_unref (bs=<optimized out>) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/block.c:5612
  0x00007f9e70df9a92 in bdrv_next (it=it@entry=0x7ffc5e3547a0) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/block/block-backend.c:576
  0x00007f9e70dfee76 in bdrv_flush_all () at 
/usr/src/debug/qemu-4.1.0-170.x86_64/block/io.c:2074
  0x00007f9e71e3a08f in do_vm_stop (state=state@entry=RUN_STATE_SHUTDOWN, 
send_stop=send_stop@entry=false) at 
/usr/src/debug/qemu-4.1.0-170.x86_64/cpus.c:1140
  0x00007f9e71e3a14c in vm_shutdown () at 
/usr/src/debug/qemu-4.1.0-170.x86_64/cpus.c:1151

During mirror job run, the VM is shutdown. During the shutdown, the mirror job 
I/O error triggers mirror_exit_commom.
In bdrv_flush_all(), bdrv_next() increase the ref to mirror_top_bs first,
and then bdrv_flush(bs) call BDRV_POLL_WHILE and executes mirror_exit_common() 
decreases ref to mirror_top_bs,
and finally bdrv_next() decreases the ref to mirror_top_bs, resulting in 
release mirror_top_bs.

Let's fix this by adding aio_context_acquire() and aio_context_release() to 
bdrv_next().

Signed-off-by: suruifeng <suruife...@huawei.com>
---
 block/block-backend.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/block/block-backend.c b/block/block-backend.c
index e0e1aff4b1..5ae745c0ab 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -593,6 +593,7 @@ BlockBackend *blk_next(BlockBackend *blk)
 BlockDriverState *bdrv_next(BdrvNextIterator *it)
 {
     BlockDriverState *bs, *old_bs;
+    AioContext *ctx = NULL;
 
     /* Must be called from the main loop */
     assert(qemu_get_current_aio_context() == qemu_get_aio_context());
@@ -613,11 +614,17 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it)
         if (it->blk) {
             blk_ref(it->blk);
         }
+       ctx = blk_get_aio_context(old_blk);
+       aio_context_acquire(ctx);
         blk_unref(old_blk);
+       aio_context_release(ctx);
 
         if (bs) {
             bdrv_ref(bs);
+           ctx = bdrv_get_aio_context(old_bs);
+           aio_context_acquire(ctx);
             bdrv_unref(old_bs);
+           aio_context_release(ctx);
             return bs;
         }
         it->phase = BDRV_NEXT_MONITOR_OWNED;
@@ -636,7 +643,10 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it)
     if (bs) {
         bdrv_ref(bs);
     }
+    ctx = bdrv_get_aio_context(old_bs);
+    aio_context_acquire(ctx);
     bdrv_unref(old_bs);
+    aio_context_release(ctx);
 
     return bs;
 }
-- 
2.27.0


Reply via email to