qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 07/16] virtio-scsi: Start/stop vhost


From: zwu . kernel
Subject: [Qemu-devel] [PATCH 07/16] virtio-scsi: Start/stop vhost
Date: Thu, 19 Apr 2012 10:39:00 +0800

From: Stefan Hajnoczi <address@hidden>

This patch starts and stops vhost as the virtio device transitions
through its status phases.  Vhost can only be started once the guest
reports its driver has successfully initialized, which means the
virtqueues have been set up by the guest.

Signed-off-by: Stefan Hajnoczi <address@hidden>
Signed-off-by: Zhi Yong Wu <address@hidden>
---
 hw/virtio-scsi.c |   44 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index 5c74523..85170d3 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -138,7 +138,6 @@ typedef struct {
     uint32_t sense_size;
     uint32_t cdb_size;
     int resetting;
-    struct vhost_virtqueue vhost_vqs[1];
     bool vhost_started;
     VHostSCSI *vhost_scsi;
 } VirtIOSCSI;
@@ -586,6 +585,42 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
     .load_request = virtio_scsi_load_request,
 };
 
+static bool virtio_scsi_started(VirtIOSCSI *s, uint8_t val)
+{
+    return (val & VIRTIO_CONFIG_S_DRIVER_OK) && s->vdev.vm_running;
+}
+
+static void virtio_scsi_set_status(VirtIODevice *vdev, uint8_t val)
+{
+    VirtIOSCSI *s = to_virtio_scsi(vdev);
+    bool start = virtio_scsi_started(s, val);
+
+    if (s->vhost_started == start) {
+        return;
+    }
+
+    if (start) {
+        int ret;
+
+        if (!vhost_dev_query(&s->vhost_scsi, vdev)) {
+            return;
+        }
+
+        ret = virtio_scsi_vhost_start(s);
+        if (ret < 0) {
+            error_report("virtio-scsi: unable to start vhost: %s\n",
+                         strerror(-ret));
+
+            /* There is no userspace virtio-scsi fallback so exit */
+            exit(1);
+        }
+    } else {
+        virtio_scsi_vhost_stop(s);
+    }
+
+    s->vhost_started = start;
+}
+
 VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
 {
     VirtIOSCSI *s;
@@ -605,6 +640,9 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, 
VirtIOSCSIConf *proxyconf)
     s->vdev.set_config = virtio_scsi_set_config;
     s->vdev.get_features = virtio_scsi_get_features;
     s->vdev.reset = virtio_scsi_reset;
+    if (s->vhost_scsi) {
+        s->vdev.set_status = virtio_scsi_set_status;
+    }
 
     s->ctrl_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,
                                    virtio_scsi_handle_ctrl);
@@ -628,6 +666,10 @@ void virtio_scsi_exit(VirtIODevice *vdev)
 {
     VirtIOSCSI *s = (VirtIOSCSI *)vdev;
     unregister_savevm(s->qdev, "virtio-scsi", s);
+
+    /* This will stop vhost backend if appropriate. */
+    virtio_scsi_set_status(vdev, 0);
+
     vhost_dev_cleanup(&s->vhost_scsi);
     virtio_cleanup(vdev);
 }
-- 
1.7.6




reply via email to

[Prev in Thread] Current Thread [Next in Thread]