diff options
author | Venkatesh Srinivas <venkateshs@google.com> | 2014-07-06 10:39:27 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-07-25 17:17:00 -0400 |
commit | 761f1193f299873236dbc21277864d70cb7ba8a3 (patch) | |
tree | a01e870c27f8512c58b51f340572f5b02e8d162a /drivers/scsi | |
parent | 938ece711c5b1ba4fa8e3b9fc8cc03843ae82a5b (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.c | 33 |
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 | */ | ||
664 | static 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 | |||
657 | static int virtscsi_abort(struct scsi_cmnd *sc) | 688 | static 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 | ||