virtio-scsi: suppress virtqueue kick during processing
The guest does not need to kick the virtqueue while we are processing it. This reduces the number of vmexits during periods of heavy I/O. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-id: 20161201192652.9509-9-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
9ef9d40261
commit
23425cc2b7
|
@ -592,26 +592,32 @@ static void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
|
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||||
{
|
{
|
||||||
VirtIOSCSIReq *req, *next;
|
VirtIOSCSIReq *req, *next;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
|
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
|
||||||
|
|
||||||
while ((req = virtio_scsi_pop_req(s, vq))) {
|
do {
|
||||||
ret = virtio_scsi_handle_cmd_req_prepare(s, req);
|
virtio_queue_set_notification(vq, 0);
|
||||||
if (!ret) {
|
|
||||||
QTAILQ_INSERT_TAIL(&reqs, req, next);
|
while ((req = virtio_scsi_pop_req(s, vq))) {
|
||||||
} else if (ret == -EINVAL) {
|
ret = virtio_scsi_handle_cmd_req_prepare(s, req);
|
||||||
/* The device is broken and shouldn't process any request */
|
if (!ret) {
|
||||||
while (!QTAILQ_EMPTY(&reqs)) {
|
QTAILQ_INSERT_TAIL(&reqs, req, next);
|
||||||
req = QTAILQ_FIRST(&reqs);
|
} else if (ret == -EINVAL) {
|
||||||
QTAILQ_REMOVE(&reqs, req, next);
|
/* The device is broken and shouldn't process any request */
|
||||||
blk_io_unplug(req->sreq->dev->conf.blk);
|
while (!QTAILQ_EMPTY(&reqs)) {
|
||||||
scsi_req_unref(req->sreq);
|
req = QTAILQ_FIRST(&reqs);
|
||||||
virtqueue_detach_element(req->vq, &req->elem, 0);
|
QTAILQ_REMOVE(&reqs, req, next);
|
||||||
virtio_scsi_free_req(req);
|
blk_io_unplug(req->sreq->dev->conf.blk);
|
||||||
|
scsi_req_unref(req->sreq);
|
||||||
|
virtqueue_detach_element(req->vq, &req->elem, 0);
|
||||||
|
virtio_scsi_free_req(req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
virtio_queue_set_notification(vq, 1);
|
||||||
|
} while (ret != -EINVAL && !virtio_queue_empty(vq));
|
||||||
|
|
||||||
QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
|
QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
|
||||||
virtio_scsi_handle_cmd_req_submit(s, req);
|
virtio_scsi_handle_cmd_req_submit(s, req);
|
||||||
|
|
Loading…
Reference in a new issue