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

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