aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorVasu Dev <vasu.dev@intel.com>2009-10-22 18:46:33 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:00:44 -0500
commit4a84067dbfce436b81779e585bf712b02ceee552 (patch)
treef787d413a11c6564ad4440d0a245f56d0e6b73bf /drivers/scsi
parent14caf44c69184ed72d46a2f883311daf27a4192f (diff)
[SCSI] add queue_depth ramp up code
Current FC HBA queue_depth ramp up code depends on last queue full time. The sdev already has last_queue_full_time field to track last queue full time but stored value is truncated by last four bits. So this patch updates last_queue_full_time without truncating last 4 bits to store full value and then updates its only current usages in scsi_track_queue_full to ignore last four bits to keep current usages same while also use this field in added ramp up code. Adds scsi_handle_queue_ramp_up to ramp up queue_depth on successful completion of IO. The scsi_handle_queue_ramp_up will do ramp up on all luns of a target, just same as ramp down done on all luns on a target. The ramp up is skipped in case the change_queue_depth is not supported by LLD or already reached to added max_queue_depth. Updates added max_queue_depth on every new update to default queue_depth value. The ramp up is also skipped if lapsed time since either last queue ramp up or down is less than LLD specified queue_ramp_up_period. Adds queue_ramp_up_period to sysfs but only if change_queue_depth is supported since ramp up and queue_ramp_up_period is needed only in case change_queue_depth is supported first. Initializes queue_ramp_up_period to 120HZ jiffies as initial default value, it is same as used in existing lpfc and qla2xxx. -v2 Combined all ramp code into this single patch. -v3 Moves max_queue_depth initialization after slave_configure is called from after slave_alloc calling done. Also adjusted max_queue_depth check to skip ramp up if current queue_depth is >= max_queue_depth. -v4 Changes sdev->queue_ramp_up_period unit to ms when using sysfs i/f to store or show its value. Signed-off-by: Vasu Dev <vasu.dev@intel.com> Tested-by: Christof Schmitt <christof.schmitt@de.ibm.com> Tested-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi.c10
-rw-r--r--drivers/scsi/scsi_error.c38
-rw-r--r--drivers/scsi/scsi_scan.c3
-rw-r--r--drivers/scsi/scsi_sysfs.c41
4 files changed, 88 insertions, 4 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index dd098cad337b..a60da5555577 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -940,10 +940,16 @@ EXPORT_SYMBOL(scsi_adjust_queue_depth);
940 */ 940 */
941int scsi_track_queue_full(struct scsi_device *sdev, int depth) 941int scsi_track_queue_full(struct scsi_device *sdev, int depth)
942{ 942{
943 if ((jiffies >> 4) == sdev->last_queue_full_time) 943
944 /*
945 * Don't let QUEUE_FULLs on the same
946 * jiffies count, they could all be from
947 * same event.
948 */
949 if ((jiffies >> 4) == (sdev->last_queue_full_time >> 4))
944 return 0; 950 return 0;
945 951
946 sdev->last_queue_full_time = (jiffies >> 4); 952 sdev->last_queue_full_time = jiffies;
947 if (sdev->last_queue_full_depth != depth) { 953 if (sdev->last_queue_full_depth != depth) {
948 sdev->last_queue_full_count = 1; 954 sdev->last_queue_full_count = 1;
949 sdev->last_queue_full_depth = depth; 955 sdev->last_queue_full_depth = depth;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 7b1e20fee906..08ed506e6059 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -331,6 +331,42 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
331 } 331 }
332} 332}
333 333
334static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
335{
336 struct scsi_host_template *sht = sdev->host->hostt;
337 struct scsi_device *tmp_sdev;
338
339 if (!sht->change_queue_depth ||
340 sdev->queue_depth >= sdev->max_queue_depth)
341 return;
342
343 if (time_before(jiffies,
344 sdev->last_queue_ramp_up + sdev->queue_ramp_up_period))
345 return;
346
347 if (time_before(jiffies,
348 sdev->last_queue_full_time + sdev->queue_ramp_up_period))
349 return;
350
351 /*
352 * Walk all devices of a target and do
353 * ramp up on them.
354 */
355 shost_for_each_device(tmp_sdev, sdev->host) {
356 if (tmp_sdev->channel != sdev->channel ||
357 tmp_sdev->id != sdev->id ||
358 tmp_sdev->queue_depth == sdev->max_queue_depth)
359 continue;
360 /*
361 * call back into LLD to increase queue_depth by one
362 * with ramp up reason code.
363 */
364 sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1,
365 SCSI_QDEPTH_RAMP_UP);
366 sdev->last_queue_ramp_up = jiffies;
367 }
368}
369
334static void scsi_handle_queue_full(struct scsi_device *sdev) 370static void scsi_handle_queue_full(struct scsi_device *sdev)
335{ 371{
336 struct scsi_host_template *sht = sdev->host->hostt; 372 struct scsi_host_template *sht = sdev->host->hostt;
@@ -393,6 +429,7 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
393 */ 429 */
394 switch (status_byte(scmd->result)) { 430 switch (status_byte(scmd->result)) {
395 case GOOD: 431 case GOOD:
432 scsi_handle_queue_ramp_up(scmd->device);
396 case COMMAND_TERMINATED: 433 case COMMAND_TERMINATED:
397 return SUCCESS; 434 return SUCCESS;
398 case CHECK_CONDITION: 435 case CHECK_CONDITION:
@@ -1425,6 +1462,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
1425 */ 1462 */
1426 return ADD_TO_MLQUEUE; 1463 return ADD_TO_MLQUEUE;
1427 case GOOD: 1464 case GOOD:
1465 scsi_handle_queue_ramp_up(scmd->device);
1428 case COMMAND_TERMINATED: 1466 case COMMAND_TERMINATED:
1429 return SUCCESS; 1467 return SUCCESS;
1430 case TASK_ABORTED: 1468 case TASK_ABORTED:
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 0547a7f44d42..50526fa207e5 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -251,6 +251,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
251 sdev->model = scsi_null_device_strs; 251 sdev->model = scsi_null_device_strs;
252 sdev->rev = scsi_null_device_strs; 252 sdev->rev = scsi_null_device_strs;
253 sdev->host = shost; 253 sdev->host = shost;
254 sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
254 sdev->id = starget->id; 255 sdev->id = starget->id;
255 sdev->lun = lun; 256 sdev->lun = lun;
256 sdev->channel = starget->channel; 257 sdev->channel = starget->channel;
@@ -941,6 +942,8 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
941 } 942 }
942 } 943 }
943 944
945 sdev->max_queue_depth = sdev->queue_depth;
946
944 /* 947 /*
945 * Ok, the device is now all set up, we can 948 * Ok, the device is now all set up, we can
946 * register it and tell the rest of the kernel 949 * register it and tell the rest of the kernel
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index a48782866b22..758598ff3b90 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -771,6 +771,8 @@ sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr,
771 if (retval < 0) 771 if (retval < 0)
772 return retval; 772 return retval;
773 773
774 sdev->max_queue_depth = sdev->queue_depth;
775
774 return count; 776 return count;
775} 777}
776 778
@@ -779,6 +781,37 @@ static struct device_attribute sdev_attr_queue_depth_rw =
779 sdev_store_queue_depth_rw); 781 sdev_store_queue_depth_rw);
780 782
781static ssize_t 783static ssize_t
784sdev_show_queue_ramp_up_period(struct device *dev,
785 struct device_attribute *attr,
786 char *buf)
787{
788 struct scsi_device *sdev;
789 sdev = to_scsi_device(dev);
790 return snprintf(buf, 20, "%u\n",
791 jiffies_to_msecs(sdev->queue_ramp_up_period));
792}
793
794static ssize_t
795sdev_store_queue_ramp_up_period(struct device *dev,
796 struct device_attribute *attr,
797 const char *buf, size_t count)
798{
799 struct scsi_device *sdev = to_scsi_device(dev);
800 unsigned long period;
801
802 if (strict_strtoul(buf, 10, &period))
803 return -EINVAL;
804
805 sdev->queue_ramp_up_period = msecs_to_jiffies(period);
806 return period;
807}
808
809static struct device_attribute sdev_attr_queue_ramp_up_period =
810 __ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
811 sdev_show_queue_ramp_up_period,
812 sdev_store_queue_ramp_up_period);
813
814static ssize_t
782sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, 815sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr,
783 const char *buf, size_t count) 816 const char *buf, size_t count)
784{ 817{
@@ -866,8 +899,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
866 } 899 }
867 900
868 /* create queue files, which may be writable, depending on the host */ 901 /* create queue files, which may be writable, depending on the host */
869 if (sdev->host->hostt->change_queue_depth) 902 if (sdev->host->hostt->change_queue_depth) {
870 error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); 903 error = device_create_file(&sdev->sdev_gendev,
904 &sdev_attr_queue_depth_rw);
905 error = device_create_file(&sdev->sdev_gendev,
906 &sdev_attr_queue_ramp_up_period);
907 }
871 else 908 else
872 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); 909 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
873 if (error) { 910 if (error) {