From: Paolo Bonzini <pbonzini@redhat.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, stefanha@redhat.com
Subject: [PATCH 2/2] virtio_scsi: implement request batching
Date: Thu, 30 May 2019 13:28:11 +0200 [thread overview]
Message-ID: <20190530112811.3066-3-pbonzini@redhat.com> (raw)
In-Reply-To: <20190530112811.3066-1-pbonzini@redhat.com>
Adding the command and kicking the virtqueue so far was done one after
another. Make the kick optional, so that we can take into account SCMD_LAST.
We also need a commit_rqs callback to kick the device if blk-mq aborts
the submission before the last request is reached.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
drivers/scsi/virtio_scsi.c | 55 +++++++++++++++++++++++++++-----------
1 file changed, 40 insertions(+), 15 deletions(-)
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 8af01777d09c..918c811cea95 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -375,14 +375,7 @@ static void virtscsi_event_done(struct virtqueue *vq)
virtscsi_vq_done(vscsi, &vscsi->event_vq, virtscsi_complete_event);
};
-/**
- * virtscsi_add_cmd - add a virtio_scsi_cmd to a virtqueue
- * @vq : the struct virtqueue we're talking about
- * @cmd : command structure
- * @req_size : size of the request buffer
- * @resp_size : size of the response buffer
- */
-static int virtscsi_add_cmd(struct virtqueue *vq,
+static int __virtscsi_add_cmd(struct virtqueue *vq,
struct virtio_scsi_cmd *cmd,
size_t req_size, size_t resp_size)
{
@@ -427,17 +420,39 @@ static int virtscsi_add_cmd(struct virtqueue *vq,
return virtqueue_add_sgs(vq, sgs, out_num, in_num, cmd, GFP_ATOMIC);
}
-static int virtscsi_kick_cmd(struct virtio_scsi_vq *vq,
+static void virtscsi_kick_vq(struct virtio_scsi_vq *vq)
+{
+ bool needs_kick;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vq->vq_lock, flags);
+ needs_kick = virtqueue_kick_prepare(vq->vq);
+ spin_unlock_irqrestore(&vq->vq_lock, flags);
+
+ if (needs_kick)
+ virtqueue_notify(vq->vq);
+}
+
+/**
+ * virtscsi_add_cmd - add a virtio_scsi_cmd to a virtqueue, optionally kick it
+ * @vq : the struct virtqueue we're talking about
+ * @cmd : command structure
+ * @req_size : size of the request buffer
+ * @resp_size : size of the response buffer
+ * @kick : whether to kick the virtqueue immediately
+ */
+static int virtscsi_add_cmd(struct virtio_scsi_vq *vq,
struct virtio_scsi_cmd *cmd,
- size_t req_size, size_t resp_size)
+ size_t req_size, size_t resp_size,
+ bool kick)
{
unsigned long flags;
int err;
bool needs_kick = false;
spin_lock_irqsave(&vq->vq_lock, flags);
- err = virtscsi_add_cmd(vq->vq, cmd, req_size, resp_size);
- if (!err)
+ err = __virtscsi_add_cmd(vq->vq, cmd, req_size, resp_size);
+ if (!err && kick)
needs_kick = virtqueue_kick_prepare(vq->vq);
spin_unlock_irqrestore(&vq->vq_lock, flags);
@@ -502,6 +517,7 @@ static int virtscsi_queuecommand(struct Scsi_Host *shost,
struct virtio_scsi *vscsi = shost_priv(shost);
struct virtio_scsi_vq *req_vq = virtscsi_pick_vq_mq(vscsi, sc);
struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc);
+ bool kick;
unsigned long flags;
int req_size;
int ret;
@@ -531,7 +547,8 @@ static int virtscsi_queuecommand(struct Scsi_Host *shost,
req_size = sizeof(cmd->req.cmd);
}
- ret = virtscsi_kick_cmd(req_vq, cmd, req_size, sizeof(cmd->resp.cmd));
+ kick = (sc->flags & SCMD_LAST) != 0;
+ ret = virtscsi_add_cmd(req_vq, cmd, req_size, sizeof(cmd->resp.cmd), kick);
if (ret == -EIO) {
cmd->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET;
spin_lock_irqsave(&req_vq->vq_lock, flags);
@@ -549,8 +566,8 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
int ret = FAILED;
cmd->comp = ∁
- if (virtscsi_kick_cmd(&vscsi->ctrl_vq, cmd,
- sizeof cmd->req.tmf, sizeof cmd->resp.tmf) < 0)
+ if (virtscsi_add_cmd(&vscsi->ctrl_vq, cmd,
+ sizeof cmd->req.tmf, sizeof cmd->resp.tmf, true) < 0)
goto out;
wait_for_completion(&comp);
@@ -664,6 +681,13 @@ static int virtscsi_map_queues(struct Scsi_Host *shost)
return blk_mq_virtio_map_queues(qmap, vscsi->vdev, 2);
}
+static void virtscsi_commit_rqs(struct Scsi_Host *shost, u16 hwq)
+{
+ struct virtio_scsi *vscsi = shost_priv(shost);
+
+ virtscsi_kick_vq(&vscsi->req_vqs[hwq]);
+}
+
/*
* The host guarantees to respond to each command, although I/O
* latencies might be higher than on bare metal. Reset the timer
@@ -681,6 +705,7 @@ static struct scsi_host_template virtscsi_host_template = {
.this_id = -1,
.cmd_size = sizeof(struct virtio_scsi_cmd),
.queuecommand = virtscsi_queuecommand,
+ .commit_rqs = virtscsi_commit_rqs,
.change_queue_depth = virtscsi_change_queue_depth,
.eh_abort_handler = virtscsi_abort,
.eh_device_reset_handler = virtscsi_device_reset,
--
2.21.0
next prev parent reply other threads:[~2019-05-30 11:28 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-30 11:28 [PATCH 0/2] scsi: add support for request batching Paolo Bonzini
2019-05-30 11:28 ` [PATCH 1/2] scsi_host: " Paolo Bonzini
2019-05-30 15:36 ` Bart Van Assche
2019-05-30 15:54 ` Paolo Bonzini
2019-05-30 17:54 ` Bart Van Assche
2019-05-31 9:12 ` Paolo Bonzini
2019-05-31 3:27 ` Ming Lei
2019-06-03 8:16 ` Paolo Bonzini
2019-07-05 1:00 ` Ming Lei
2019-06-04 22:40 ` Bart Van Assche
2019-06-19 8:11 ` Hannes Reinecke
2019-06-19 10:31 ` Paolo Bonzini
2019-07-04 13:19 ` Paolo Bonzini
2019-07-05 7:12 ` Hannes Reinecke
2019-07-05 7:44 ` Stefan Hajnoczi
2019-07-05 7:51 ` Hannes Reinecke
2019-05-30 11:28 ` Paolo Bonzini [this message]
2019-05-30 17:28 ` [PATCH 2/2] virtio_scsi: implement " Bart Van Assche
2019-05-31 9:03 ` Paolo Bonzini
2019-07-05 7:52 ` Hannes Reinecke
2019-07-08 9:47 ` Ming Lei
2019-06-10 12:36 ` [PATCH 0/2] scsi: add support for " Stefan Hajnoczi
2019-06-26 13:51 ` Paolo Bonzini
2019-06-26 14:14 ` Douglas Gilbert
2019-06-26 14:50 ` Paolo Bonzini
2019-06-27 3:37 ` Martin K. Petersen
2019-06-27 8:17 ` Paolo Bonzini
2019-07-05 7:13 ` Hannes Reinecke
2019-07-05 11:58 ` Paolo Bonzini
2019-07-12 1:37 ` Martin K. Petersen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190530112811.3066-3-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=jejb@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).