diff options
author | Fam Zheng <famz@redhat.com> | 2014-10-19 12:47:42 +0800 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-10-23 16:41:22 +0200 |
commit | 3e2b2a9c49f44926b995495be5e94e61e4f29f5e (patch) | |
tree | 0e637dd056123a66c2c8eaed854e97c8cd894808 /hw/scsi | |
parent | e40830afa1cff3ffdc37bdfdd40d80860074636c (diff) |
virtio-scsi-dataplane: Add op blocker
We need this to protect dataplane thread from race conditions with block
jobs until the latter is made dataplane-safe.
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/scsi')
-rw-r--r-- | hw/scsi/virtio-scsi-dataplane.c | 4 | ||||
-rw-r--r-- | hw/scsi/virtio-scsi.c | 19 |
2 files changed, 21 insertions, 2 deletions
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 48dcfd2852..1f77635774 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -155,6 +155,8 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s) s->dataplane_starting = true; + assert(!s->blocker); + error_setg(&s->blocker, "block device is in use by data plane"); /* Set up guest notifier (irq) */ rc = k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, true); if (rc != 0) { @@ -195,6 +197,8 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s) if (!s->dataplane_started || s->dataplane_stopping) { return; } + error_free(s->blocker); + s->blocker = NULL; s->dataplane_stopping = true; assert(s->ctx == iothread_get_aio_context(vs->conf.iothread)); diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index a1725b8f48..2d2612bf05 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -742,9 +742,18 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); + VirtIOSCSI *s = VIRTIO_SCSI(vdev); + SCSIDevice *sd = SCSI_DEVICE(dev); + + if (s->ctx && !s->dataplane_disabled) { + if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { + return; + } + blk_op_block_all(sd->conf.blk, s->blocker); + } if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { - virtio_scsi_push_event(VIRTIO_SCSI(hotplug_dev), SCSI_DEVICE(dev), + virtio_scsi_push_event(s, sd, VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN); } @@ -754,12 +763,18 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); + VirtIOSCSI *s = VIRTIO_SCSI(vdev); + SCSIDevice *sd = SCSI_DEVICE(dev); if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { - virtio_scsi_push_event(VIRTIO_SCSI(hotplug_dev), SCSI_DEVICE(dev), + virtio_scsi_push_event(s, sd, VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED); } + + if (s->ctx) { + blk_op_unblock_all(sd->conf.blk, s->blocker); + } qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); } |