From: Fam Zheng Date: Tue, 23 Sep 2014 07:49:28 +0000 (+0800) Subject: virtio-scsi: Batched prepare for cmd reqs X-Git-Tag: qemu-xen-4.6.0-rc1~144^2~11 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=1880ad4f4e3b49f15c55e816d66b9690b3ede00c;p=qemu-upstream-unstable.git virtio-scsi: Batched prepare for cmd reqs Queue the popped requests while calling virtio_scsi_handle_cmd_req_prepare(), then submit them after all prepared. Signed-off-by: Fam Zheng Signed-off-by: Paolo Bonzini --- diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 11f570540..b778e051f 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -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 */ diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 6cf070f70..395178e94 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -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, diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 1cc759a64..60dbfc99a 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -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;