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 <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Fam Zheng 2014-09-23 15:49:28 +08:00 committed by Paolo Bonzini
parent 359eea71d9
commit 1880ad4f4e
3 changed files with 18 additions and 4 deletions

View File

@ -122,14 +122,19 @@ static void virtio_scsi_iothread_handle_cmd(EventNotifier *notifier)
VirtIOSCSIVring *vring = container_of(notifier, VirtIOSCSIVring *vring = container_of(notifier,
VirtIOSCSIVring, host_notifier); VirtIOSCSIVring, host_notifier);
VirtIOSCSI *s = (VirtIOSCSI *)vring->parent; VirtIOSCSI *s = (VirtIOSCSI *)vring->parent;
VirtIOSCSIReq *req; VirtIOSCSIReq *req, *next;
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
event_notifier_test_and_clear(notifier); event_notifier_test_and_clear(notifier);
while ((req = virtio_scsi_pop_req_vring(s, vring))) { while ((req = virtio_scsi_pop_req_vring(s, vring))) {
if (virtio_scsi_handle_cmd_req_prepare(s, req)) { 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 */ /* Context: QEMU global mutex held */

View File

@ -502,7 +502,8 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
{ {
/* use non-QOM casts in the data path */ /* use non-QOM casts in the data path */
VirtIOSCSI *s = (VirtIOSCSI *)vdev; VirtIOSCSI *s = (VirtIOSCSI *)vdev;
VirtIOSCSIReq *req; VirtIOSCSIReq *req, *next;
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
if (s->ctx && !s->dataplane_disabled) { if (s->ctx && !s->dataplane_disabled) {
virtio_scsi_dataplane_start(s); 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))) { while ((req = virtio_scsi_pop_req(s, vq))) {
if (virtio_scsi_handle_cmd_req_prepare(s, req)) { 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, static void virtio_scsi_get_config(VirtIODevice *vdev,

View File

@ -213,6 +213,10 @@ typedef struct VirtIOSCSIReq {
VirtQueueElement elem; VirtQueueElement elem;
/* Set by dataplane code. */ /* Set by dataplane code. */
VirtIOSCSIVring *vring; VirtIOSCSIVring *vring;
/* Used for two-stage request submission */
QTAILQ_ENTRY(VirtIOSCSIReq) next;
SCSIRequest *sreq; SCSIRequest *sreq;
size_t resp_size; size_t resp_size;
enum SCSIXferMode mode; enum SCSIXferMode mode;