Blame SOURCES/kvm-blockdev-acquire-aio_context-for-bitmap-add-remove.patch

7711c0
From 04c5a9797c3bdf379ffad1f159eccfcdca12475f Mon Sep 17 00:00:00 2001
7711c0
From: John Snow <jsnow@redhat.com>
7711c0
Date: Wed, 20 Mar 2019 23:55:08 +0100
7711c0
Subject: [PATCH 046/163] blockdev: acquire aio_context for bitmap add/remove
7711c0
7711c0
RH-Author: John Snow <jsnow@redhat.com>
7711c0
Message-id: <20190320235508.17673-2-jsnow@redhat.com>
7711c0
Patchwork-id: 85031
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 1/1] blockdev: acquire aio_context for bitmap add/remove
7711c0
Bugzilla: 1672010
7711c0
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7711c0
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
7711c0
When bitmaps are persistent, they may incur a disk read or write when bitmaps
7711c0
are added or removed. For configurations like virtio-dataplane, failing to
7711c0
acquire this lock will abort QEMU when disk IO occurs.
7711c0
7711c0
We used to acquire aio_context as part of the bitmap lookup, so re-introduce
7711c0
the lock for just the cases that have an IO penalty. Commit 2119882c removed
7711c0
these locks, and I failed to notice this when we committed fd5ae4cc, so this
7711c0
has been broken since persistent bitmaps were introduced.
7711c0
7711c0
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1672010
7711c0
Reported-By: Aihua Liang <aliang@redhat.com>
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Reviewed-by: Eric Blake <eblake@redhat.com>
7711c0
Message-id: 20190218233154.19303-1-jsnow@redhat.com
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
(cherry picked from commit 0a6c86d024c52b1e66d4f7ec01a3bb8ea2600145)
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 blockdev.c | 26 ++++++++++++++++++++------
7711c0
 1 file changed, 20 insertions(+), 6 deletions(-)
7711c0
7711c0
diff --git a/blockdev.c b/blockdev.c
7711c0
index 47db9bb..f437896 100644
7711c0
--- a/blockdev.c
7711c0
+++ b/blockdev.c
7711c0
@@ -2973,6 +2973,7 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
7711c0
 {
7711c0
     BlockDriverState *bs;
7711c0
     BdrvDirtyBitmap *bitmap;
7711c0
+    AioContext *aio_context = NULL;
7711c0
 
7711c0
     if (!name || name[0] == '\0') {
7711c0
         error_setg(errp, "Bitmap name cannot be empty");
7711c0
@@ -3007,15 +3008,17 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
7711c0
         disabled = false;
7711c0
     }
7711c0
 
7711c0
-    if (persistent &&
7711c0
-        !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
7711c0
-    {
7711c0
-        return;
7711c0
+    if (persistent) {
7711c0
+        aio_context = bdrv_get_aio_context(bs);
7711c0
+        aio_context_acquire(aio_context);
7711c0
+        if (!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) {
7711c0
+            goto out;
7711c0
+        }
7711c0
     }
7711c0
 
7711c0
     bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
7711c0
     if (bitmap == NULL) {
7711c0
-        return;
7711c0
+        goto out;
7711c0
     }
7711c0
 
7711c0
     if (disabled) {
7711c0
@@ -3023,6 +3026,10 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
7711c0
     }
7711c0
 
7711c0
     bdrv_dirty_bitmap_set_persistance(bitmap, persistent);
7711c0
+ out:
7711c0
+    if (aio_context) {
7711c0
+        aio_context_release(aio_context);
7711c0
+    }
7711c0
 }
7711c0
 
7711c0
 void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
7711c0
@@ -3031,6 +3038,7 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
7711c0
     BlockDriverState *bs;
7711c0
     BdrvDirtyBitmap *bitmap;
7711c0
     Error *local_err = NULL;
7711c0
+    AioContext *aio_context = NULL;
7711c0
 
7711c0
     bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
7711c0
     if (!bitmap || !bs) {
7711c0
@@ -3045,14 +3053,20 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
7711c0
     }
7711c0
 
7711c0
     if (bdrv_dirty_bitmap_get_persistance(bitmap)) {
7711c0
+        aio_context = bdrv_get_aio_context(bs);
7711c0
+        aio_context_acquire(aio_context);
7711c0
         bdrv_remove_persistent_dirty_bitmap(bs, name, &local_err);
7711c0
         if (local_err != NULL) {
7711c0
             error_propagate(errp, local_err);
7711c0
-            return;
7711c0
+            goto out;
7711c0
         }
7711c0
     }
7711c0
 
7711c0
     bdrv_release_dirty_bitmap(bs, bitmap);
7711c0
+ out:
7711c0
+    if (aio_context) {
7711c0
+        aio_context_release(aio_context);
7711c0
+    }
7711c0
 }
7711c0
 
7711c0
 /**
7711c0
-- 
7711c0
1.8.3.1
7711c0