Blame SOURCES/kvm-scsi-disk-Acquire-the-AioContext-in-scsi_-_realize.patch

7711c0
From e47b913ba52ead235fd3a03916d62ce49254c575 Mon Sep 17 00:00:00 2001
7711c0
From: Markus Armbruster <armbru@redhat.com>
7711c0
Date: Fri, 10 May 2019 13:28:24 +0200
7711c0
Subject: [PATCH 21/53] scsi-disk: Acquire the AioContext in scsi_*_realize()
7711c0
7711c0
RH-Author: Markus Armbruster <armbru@redhat.com>
7711c0
Message-id: <20190510132825.29833-3-armbru@redhat.com>
7711c0
Patchwork-id: 87265
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 2/3] scsi-disk: Acquire the AioContext in scsi_*_realize()
7711c0
Bugzilla: 1673397 1673402
7711c0
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
7711c0
7711c0
From: Alberto Garcia <berto@igalia.com>
7711c0
7711c0
This fixes a crash when attaching two disks with the same blockdev to
7711c0
a SCSI device that is using iothreads. Test case included.
7711c0
7711c0
Signed-off-by: Alberto Garcia <berto@igalia.com>
7711c0
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7711c0
(cherry picked from commit 3ff35ba391134e4e43ab96152deb38a62e62f858)
7711c0
[Trivial conflict in hw/scsi/scsi-disk.c due to lack of commit
7711c0
51f43d5792e resolved]
7711c0
Signed-off-by: Markus Armbruster <armbru@redhat.com>
7711c0
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 hw/scsi/scsi-disk.c        | 23 ++++++++++++++++++++---
7711c0
 tests/qemu-iotests/240     | 18 ++++++++++++++++++
7711c0
 tests/qemu-iotests/240.out | 16 ++++++++++++++++
7711c0
 3 files changed, 54 insertions(+), 3 deletions(-)
7711c0
7711c0
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
7711c0
index 8033d7e..6cc5ccc 100644
7711c0
--- a/hw/scsi/scsi-disk.c
7711c0
+++ b/hw/scsi/scsi-disk.c
7711c0
@@ -2386,10 +2386,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
7711c0
 static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
7711c0
 {
7711c0
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
7711c0
+    AioContext *ctx = NULL;
7711c0
     /* can happen for devices without drive. The error message for missing
7711c0
      * backend will be issued in scsi_realize
7711c0
      */
7711c0
     if (s->qdev.conf.blk) {
7711c0
+        ctx = blk_get_aio_context(s->qdev.conf.blk);
7711c0
+        aio_context_acquire(ctx);
7711c0
         blkconf_blocksizes(&s->qdev.conf);
7711c0
     }
7711c0
     s->qdev.blocksize = s->qdev.conf.logical_block_size;
7711c0
@@ -2398,11 +2401,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
7711c0
         s->product = g_strdup("QEMU HARDDISK");
7711c0
     }
7711c0
     scsi_realize(&s->qdev, errp);
7711c0
+    if (ctx) {
7711c0
+        aio_context_release(ctx);
7711c0
+    }
7711c0
 }
7711c0
 
7711c0
 static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
7711c0
 {
7711c0
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
7711c0
+    AioContext *ctx;
7711c0
     int ret;
7711c0
 
7711c0
     if (!dev->conf.blk) {
7711c0
@@ -2413,6 +2420,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
7711c0
         assert(ret == 0);
7711c0
     }
7711c0
 
7711c0
+    ctx = blk_get_aio_context(dev->conf.blk);
7711c0
+    aio_context_acquire(ctx);
7711c0
     s->qdev.blocksize = 2048;
7711c0
     s->qdev.type = TYPE_ROM;
7711c0
     s->features |= 1 << SCSI_DISK_F_REMOVABLE;
7711c0
@@ -2420,6 +2429,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
7711c0
         s->product = g_strdup("QEMU CD-ROM");
7711c0
     }
7711c0
     scsi_realize(&s->qdev, errp);
7711c0
+    aio_context_release(ctx);
7711c0
 }
7711c0
 
7711c0
 static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
7711c0
@@ -2558,6 +2568,7 @@ static int get_device_type(SCSIDiskState *s)
7711c0
 static void scsi_block_realize(SCSIDevice *dev, Error **errp)
7711c0
 {
7711c0
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
7711c0
+    AioContext *ctx;
7711c0
     int sg_version;
7711c0
     int rc;
7711c0
 
7711c0
@@ -2566,6 +2577,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
7711c0
         return;
7711c0
     }
7711c0
 
7711c0
+    ctx = blk_get_aio_context(s->qdev.conf.blk);
7711c0
+    aio_context_acquire(ctx);
7711c0
+
7711c0
     /* check we are using a driver managing SG_IO (version 3 and after) */
7711c0
     rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
7711c0
     if (rc < 0) {
7711c0
@@ -2573,18 +2587,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
7711c0
         if (rc != -EPERM) {
7711c0
             error_append_hint(errp, "Is this a SCSI device?\n");
7711c0
         }
7711c0
-        return;
7711c0
+        goto out;
7711c0
     }
7711c0
     if (sg_version < 30000) {
7711c0
         error_setg(errp, "scsi generic interface too old");
7711c0
-        return;
7711c0
+        goto out;
7711c0
     }
7711c0
 
7711c0
     /* get device type from INQUIRY data */
7711c0
     rc = get_device_type(s);
7711c0
     if (rc < 0) {
7711c0
         error_setg(errp, "INQUIRY failed");
7711c0
-        return;
7711c0
+        goto out;
7711c0
     }
7711c0
 
7711c0
     /* Make a guess for the block size, we'll fix it when the guest sends.
7711c0
@@ -2604,6 +2618,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
7711c0
 
7711c0
     scsi_realize(&s->qdev, errp);
7711c0
     scsi_generic_read_device_inquiry(&s->qdev);
7711c0
+
7711c0
+out:
7711c0
+    aio_context_release(ctx);
7711c0
 }
7711c0
 
7711c0
 typedef struct SCSIBlockReq {
7711c0
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
7711c0
index ead7ee0..5d499c9 100755
7711c0
--- a/tests/qemu-iotests/240
7711c0
+++ b/tests/qemu-iotests/240
7711c0
@@ -83,6 +83,24 @@ run_qemu <
7711c0
 { "execute": "quit"}
7711c0
 EOF
7711c0
 
7711c0
+echo
7711c0
+echo === Attach two SCSI disks using the same block device and the same iothread ===
7711c0
+echo
7711c0
+
7711c0
+run_qemu <
7711c0
+{ "execute": "qmp_capabilities" }
7711c0
+{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true}}
7711c0
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
7711c0
+{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
7711c0
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0"}}
7711c0
+{ "execute": "device_add", "arguments": {"id": "scsi-hd1", "driver": "scsi-hd", "drive": "hd0"}}
7711c0
+{ "execute": "device_del", "arguments": {"id": "scsi-hd0"}}
7711c0
+{ "execute": "device_del", "arguments": {"id": "scsi-hd1"}}
7711c0
+{ "execute": "device_del", "arguments": {"id": "scsi0"}}
7711c0
+{ "execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
7711c0
+{ "execute": "quit"}
7711c0
+EOF
7711c0
+
7711c0
 # success, all done
7711c0
 echo "*** done"
7711c0
 rm -f $seq.full
7711c0
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
7711c0
index 432d981..701cb5c 100644
7711c0
--- a/tests/qemu-iotests/240.out
7711c0
+++ b/tests/qemu-iotests/240.out
7711c0
@@ -15,4 +15,20 @@ QMP_VERSION
7711c0
 {"return": {}}
7711c0
 {"return": {}}
7711c0
 {"return": {}}
7711c0
+
7711c0
+=== Attach two SCSI disks using the same block device and the same iothread ===
7711c0
+
7711c0
+Testing:
7711c0
+QMP_VERSION
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
+{"return": {}}
7711c0
 *** done
7711c0
-- 
7711c0
1.8.3.1
7711c0