virtio-scsi: Batched prepare for cmd reqs
authorFam Zheng <famz@redhat.com>
Tue, 23 Sep 2014 07:49:28 +0000 (15:49 +0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 30 Sep 2014 09:11:20 +0000 (11:11 +0200)
Queue the popped requests while calling
virtio_scsi_handle_cmd_req_prepare(), then submit them after all
prepared.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
hw/scsi/virtio-scsi-dataplane.c
hw/scsi/virtio-scsi.c
include/hw/virtio/virtio-scsi.h

index 11f5705..b778e05 100644 (file)
@@ -122,14 +122,19 @@ static void virtio_scsi_iothread_handle_cmd(EventNotifier *notifier)
     VirtIOSCSIVring *vring = container_of(notifier,
                                           VirtIOSCSIVring, host_notifier);
     VirtIOSCSI *s = (VirtIOSCSI *)vring->parent;
-    VirtIOSCSIReq *req;
+    VirtIOSCSIReq *req, *next;
+    QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
 
     event_notifier_test_and_clear(notifier);
     while ((req = virtio_scsi_pop_req_vring(s, vring))) {
         if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
-            virtio_scsi_handle_cmd_req_submit(s, req);
+            QTAILQ_INSERT_TAIL(&reqs, req, next);
         }
     }
+
+    QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
+        virtio_scsi_handle_cmd_req_submit(s, req);
+    }
 }
 
 /* Context: QEMU global mutex held */
index 6cf070f..395178e 100644 (file)
@@ -502,7 +502,8 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
 {
     /* use non-QOM casts in the data path */
     VirtIOSCSI *s = (VirtIOSCSI *)vdev;
-    VirtIOSCSIReq *req;
+    VirtIOSCSIReq *req, *next;
+    QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
 
     if (s->ctx && !s->dataplane_disabled) {
         virtio_scsi_dataplane_start(s);
@@ -510,9 +511,13 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
     }
     while ((req = virtio_scsi_pop_req(s, vq))) {
         if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
-            virtio_scsi_handle_cmd_req_submit(s, req);
+            QTAILQ_INSERT_TAIL(&reqs, req, next);
         }
     }
+
+    QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
+        virtio_scsi_handle_cmd_req_submit(s, req);
+    }
 }
 
 static void virtio_scsi_get_config(VirtIODevice *vdev,
index 1cc759a..60dbfc9 100644 (file)
@@ -213,6 +213,10 @@ typedef struct VirtIOSCSIReq {
     VirtQueueElement elem;
     /* Set by dataplane code. */
     VirtIOSCSIVring *vring;
+
+    /* Used for two-stage request submission */
+    QTAILQ_ENTRY(VirtIOSCSIReq) next;
+
     SCSIRequest *sreq;
     size_t resp_size;
     enum SCSIXferMode mode;