aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorVenkatesh Srinivas <venkateshs@google.com>2014-07-06 10:39:27 -0400
committerChristoph Hellwig <hch@lst.de>2014-07-25 17:17:00 -0400
commit761f1193f299873236dbc21277864d70cb7ba8a3 (patch)
treea01e870c27f8512c58b51f340572f5b02e8d162a /drivers/scsi
parent938ece711c5b1ba4fa8e3b9fc8cc03843ae82a5b (diff)
virtio-scsi: Implement change_queue_depth for virtscsi targets
change_queue_depth allows changing per-target queue depth via sysfs. It also allows the SCSI midlayer to ramp down the number of concurrent inflight requests in response to a SCSI BUSY status response and allows the midlayer to ramp the count back up to the device maximum when the BUSY condition has resolved. Signed-off-by: Venkatesh Srinivas <venkateshs@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/virtio_scsi.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index cdce502c3c46..eee1bc0b506e 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -27,6 +27,7 @@
27#include <scsi/scsi_host.h> 27#include <scsi/scsi_host.h>
28#include <scsi/scsi_device.h> 28#include <scsi/scsi_device.h>
29#include <scsi/scsi_cmnd.h> 29#include <scsi/scsi_cmnd.h>
30#include <scsi/scsi_tcq.h>
30#include <linux/seqlock.h> 31#include <linux/seqlock.h>
31 32
32#define VIRTIO_SCSI_MEMPOOL_SZ 64 33#define VIRTIO_SCSI_MEMPOOL_SZ 64
@@ -654,6 +655,36 @@ static int virtscsi_device_reset(struct scsi_cmnd *sc)
654 return virtscsi_tmf(vscsi, cmd); 655 return virtscsi_tmf(vscsi, cmd);
655} 656}
656 657
658/**
659 * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth
660 * @sdev: Virtscsi target whose queue depth to change
661 * @qdepth: New queue depth
662 * @reason: Reason for the queue depth change.
663 */
664static int virtscsi_change_queue_depth(struct scsi_device *sdev,
665 int qdepth,
666 int reason)
667{
668 struct Scsi_Host *shost = sdev->host;
669 int max_depth = shost->cmd_per_lun;
670
671 switch (reason) {
672 case SCSI_QDEPTH_QFULL: /* Drop qdepth in response to BUSY state */
673 scsi_track_queue_full(sdev, qdepth);
674 break;
675 case SCSI_QDEPTH_RAMP_UP: /* Raise qdepth after BUSY state resolved */
676 case SCSI_QDEPTH_DEFAULT: /* Manual change via sysfs */
677 scsi_adjust_queue_depth(sdev,
678 scsi_get_tag_type(sdev),
679 min(max_depth, qdepth));
680 break;
681 default:
682 return -EOPNOTSUPP;
683 }
684
685 return sdev->queue_depth;
686}
687
657static int virtscsi_abort(struct scsi_cmnd *sc) 688static int virtscsi_abort(struct scsi_cmnd *sc)
658{ 689{
659 struct virtio_scsi *vscsi = shost_priv(sc->device->host); 690 struct virtio_scsi *vscsi = shost_priv(sc->device->host);
@@ -709,6 +740,7 @@ static struct scsi_host_template virtscsi_host_template_single = {
709 .this_id = -1, 740 .this_id = -1,
710 .cmd_size = sizeof(struct virtio_scsi_cmd), 741 .cmd_size = sizeof(struct virtio_scsi_cmd),
711 .queuecommand = virtscsi_queuecommand_single, 742 .queuecommand = virtscsi_queuecommand_single,
743 .change_queue_depth = virtscsi_change_queue_depth,
712 .eh_abort_handler = virtscsi_abort, 744 .eh_abort_handler = virtscsi_abort,
713 .eh_device_reset_handler = virtscsi_device_reset, 745 .eh_device_reset_handler = virtscsi_device_reset,
714 746
@@ -726,6 +758,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {
726 .this_id = -1, 758 .this_id = -1,
727 .cmd_size = sizeof(struct virtio_scsi_cmd), 759 .cmd_size = sizeof(struct virtio_scsi_cmd),
728 .queuecommand = virtscsi_queuecommand_multi, 760 .queuecommand = virtscsi_queuecommand_multi,
761 .change_queue_depth = virtscsi_change_queue_depth,
729 .eh_abort_handler = virtscsi_abort, 762 .eh_abort_handler = virtscsi_abort,
730 .eh_device_reset_handler = virtscsi_device_reset, 763 .eh_device_reset_handler = virtscsi_device_reset,
731 764