[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 03/20] virtio-scsi: avoid race between unplug and transport ev
From: |
Stefan Hajnoczi |
Subject: |
[PATCH v4 03/20] virtio-scsi: avoid race between unplug and transport event |
Date: |
Tue, 25 Apr 2023 13:26:59 -0400 |
Only report a transport reset event to the guest after the SCSIDevice
has been unrealized by qdev_simple_device_unplug_cb().
qdev_simple_device_unplug_cb() sets the SCSIDevice's qdev.realized field
to false so that scsi_device_find/get() no longer see it.
scsi_target_emulate_report_luns() also needs to be updated to filter out
SCSIDevices that are unrealized.
These changes ensure that the guest driver does not see the SCSIDevice
that's being unplugged if it responds very quickly to the transport
reset event.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/scsi/scsi-bus.c | 3 ++-
hw/scsi/virtio-scsi.c | 18 +++++++++---------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 07275fb631..64d7311757 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -486,7 +486,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq
*r)
DeviceState *qdev = kid->child;
SCSIDevice *dev = SCSI_DEVICE(qdev);
- if (dev->channel == channel && dev->id == id && dev->lun != 0) {
+ if (dev->channel == channel && dev->id == id && dev->lun != 0 &&
+ qdev_is_realized(&dev->qdev)) {
store_lun(tmp, dev->lun);
g_byte_array_append(buf, tmp, 8);
len += 8;
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 612c525d9d..000961446c 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -1063,15 +1063,6 @@ static void virtio_scsi_hotunplug(HotplugHandler
*hotplug_dev, DeviceState *dev,
SCSIDevice *sd = SCSI_DEVICE(dev);
AioContext *ctx = s->ctx ?: qemu_get_aio_context();
- if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
- virtio_scsi_acquire(s);
- virtio_scsi_push_event(s, sd,
- VIRTIO_SCSI_T_TRANSPORT_RESET,
- VIRTIO_SCSI_EVT_RESET_REMOVED);
- scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED));
- virtio_scsi_release(s);
- }
-
aio_disable_external(ctx);
qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
aio_enable_external(ctx);
@@ -1082,6 +1073,15 @@ static void virtio_scsi_hotunplug(HotplugHandler
*hotplug_dev, DeviceState *dev,
blk_set_aio_context(sd->conf.blk, qemu_get_aio_context(), NULL);
virtio_scsi_release(s);
}
+
+ if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
+ virtio_scsi_acquire(s);
+ virtio_scsi_push_event(s, sd,
+ VIRTIO_SCSI_T_TRANSPORT_RESET,
+ VIRTIO_SCSI_EVT_RESET_REMOVED);
+ scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED));
+ virtio_scsi_release(s);
+ }
}
static struct SCSIBusInfo virtio_scsi_scsi_info = {
--
2.39.2
- [PATCH v4 00/20] block: remove aio_disable_external() API, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 03/20] virtio-scsi: avoid race between unplug and transport event,
Stefan Hajnoczi <=
- [PATCH v4 01/20] block-backend: split blk_do_set_aio_context(), Stefan Hajnoczi, 2023/04/25
- [PATCH v4 02/20] hw/qdev: introduce qdev_is_realized() helper, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 04/20] virtio-scsi: stop using aio_disable_external() during unplug, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 06/20] block/export: wait for vhost-user-blk requests when draining, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 05/20] util/vhost-user-server: rename refcount to in_flight counter, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 07/20] block/export: stop using is_external in vhost-user-blk server, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 08/20] hw/xen: do not use aio_set_fd_handler(is_external=true) in xen_xenstore, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 09/20] block: add blk_in_drain() API, Stefan Hajnoczi, 2023/04/25
- [PATCH v4 11/20] xen-block: implement BlockDevOps->drained_begin(), Stefan Hajnoczi, 2023/04/25