Blame SOURCES/kvm-block-fix-QEMU-crash-with-scsi-hd-and-drive_del.patch

383d26
From 08e7b4d1dc3f71818fec2ebd5f189142011969a9 Mon Sep 17 00:00:00 2001
383d26
From: Kevin Wolf <kwolf@redhat.com>
383d26
Date: Thu, 12 Jul 2018 16:06:19 +0200
383d26
Subject: [PATCH 41/89] block: fix QEMU crash with scsi-hd and drive_del
383d26
383d26
RH-Author: Kevin Wolf <kwolf@redhat.com>
383d26
Message-id: <20180712160619.30712-2-kwolf@redhat.com>
383d26
Patchwork-id: 81334
383d26
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 1/1] block: fix QEMU crash with scsi-hd and drive_del
383d26
Bugzilla: 1599515
383d26
RH-Acked-by: Fam Zheng <famz@redhat.com>
383d26
RH-Acked-by: Max Reitz <mreitz@redhat.com>
383d26
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
383d26
383d26
From: Greg Kurz <groug@kaod.org>
383d26
383d26
Removing a drive with drive_del while it is being used to run an I/O
383d26
intensive workload can cause QEMU to crash.
383d26
383d26
An AIO flush can yield at some point:
383d26
383d26
blk_aio_flush_entry()
383d26
 blk_co_flush(blk)
383d26
  bdrv_co_flush(blk->root->bs)
383d26
   ...
383d26
    qemu_coroutine_yield()
383d26
383d26
and let the HMP command to run, free blk->root and give control
383d26
back to the AIO flush:
383d26
383d26
    hmp_drive_del()
383d26
     blk_remove_bs()
383d26
      bdrv_root_unref_child(blk->root)
383d26
       child_bs = blk->root->bs
383d26
       bdrv_detach_child(blk->root)
383d26
        bdrv_replace_child(blk->root, NULL)
383d26
         blk->root->bs = NULL
383d26
        g_free(blk->root) <============== blk->root becomes stale
383d26
       bdrv_unref(child_bs)
383d26
        bdrv_delete(child_bs)
383d26
         bdrv_close()
383d26
          bdrv_drained_begin()
383d26
           bdrv_do_drained_begin()
383d26
            bdrv_drain_recurse()
383d26
             aio_poll()
383d26
              ...
383d26
              qemu_coroutine_switch()
383d26
383d26
and the AIO flush completion ends up dereferencing blk->root:
383d26
383d26
  blk_aio_complete()
383d26
   scsi_aio_complete()
383d26
    blk_get_aio_context(blk)
383d26
     bs = blk_bs(blk)
383d26
 ie, bs = blk->root ? blk->root->bs : NULL
383d26
            ^^^^^
383d26
            stale
383d26
383d26
The problem is that we should avoid making block driver graph
383d26
changes while we have in-flight requests. Let's drain all I/O
383d26
for this BB before calling bdrv_root_unref_child().
383d26
383d26
Signed-off-by: Greg Kurz <groug@kaod.org>
383d26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
383d26
(cherry picked from commit f45280cbf66d8e58224f6a253d0ae2aa72cc6280)
383d26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 block/block-backend.c | 5 +++++
383d26
 1 file changed, 5 insertions(+)
383d26
383d26
diff --git a/block/block-backend.c b/block/block-backend.c
383d26
index 56ae535..a469fc6 100644
383d26
--- a/block/block-backend.c
383d26
+++ b/block/block-backend.c
383d26
@@ -768,6 +768,11 @@ void blk_remove_bs(BlockBackend *blk)
383d26
 
383d26
     blk_update_root_state(blk);
383d26
 
383d26
+    /* bdrv_root_unref_child() will cause blk->root to become stale and may
383d26
+     * switch to a completion coroutine later on. Let's drain all I/O here
383d26
+     * to avoid that and a potential QEMU crash.
383d26
+     */
383d26
+    blk_drain(blk);
383d26
     bdrv_root_unref_child(blk->root);
383d26
     blk->root = NULL;
383d26
 }
383d26
-- 
383d26
1.8.3.1
383d26