Commit 4a84067dbfce436b81779e585bf712b02ceee552
Committed by
James Bottomley
1 parent
14caf44c69
Exists in
master
and in
4 other branches
[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>
Showing 5 changed files with 94 additions and 7 deletions Side-by-side Diff
drivers/scsi/scsi.c
... | ... | @@ -940,10 +940,16 @@ |
940 | 940 | */ |
941 | 941 | int 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 | 950 | return 0; |
945 | 951 | |
946 | - sdev->last_queue_full_time = (jiffies >> 4); | |
952 | + sdev->last_queue_full_time = jiffies; | |
947 | 953 | if (sdev->last_queue_full_depth != depth) { |
948 | 954 | sdev->last_queue_full_count = 1; |
949 | 955 | sdev->last_queue_full_depth = depth; |
drivers/scsi/scsi_error.c
... | ... | @@ -331,6 +331,42 @@ |
331 | 331 | } |
332 | 332 | } |
333 | 333 | |
334 | +static 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 | + | |
334 | 370 | static void scsi_handle_queue_full(struct scsi_device *sdev) |
335 | 371 | { |
336 | 372 | struct scsi_host_template *sht = sdev->host->hostt; |
... | ... | @@ -393,6 +429,7 @@ |
393 | 429 | */ |
394 | 430 | switch (status_byte(scmd->result)) { |
395 | 431 | case GOOD: |
432 | + scsi_handle_queue_ramp_up(scmd->device); | |
396 | 433 | case COMMAND_TERMINATED: |
397 | 434 | return SUCCESS; |
398 | 435 | case CHECK_CONDITION: |
... | ... | @@ -1425,6 +1462,7 @@ |
1425 | 1462 | */ |
1426 | 1463 | return ADD_TO_MLQUEUE; |
1427 | 1464 | case GOOD: |
1465 | + scsi_handle_queue_ramp_up(scmd->device); | |
1428 | 1466 | case COMMAND_TERMINATED: |
1429 | 1467 | return SUCCESS; |
1430 | 1468 | case TASK_ABORTED: |
drivers/scsi/scsi_scan.c
... | ... | @@ -251,6 +251,7 @@ |
251 | 251 | sdev->model = scsi_null_device_strs; |
252 | 252 | sdev->rev = scsi_null_device_strs; |
253 | 253 | sdev->host = shost; |
254 | + sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD; | |
254 | 255 | sdev->id = starget->id; |
255 | 256 | sdev->lun = lun; |
256 | 257 | sdev->channel = starget->channel; |
... | ... | @@ -940,6 +941,8 @@ |
940 | 941 | return SCSI_SCAN_NO_RESPONSE; |
941 | 942 | } |
942 | 943 | } |
944 | + | |
945 | + sdev->max_queue_depth = sdev->queue_depth; | |
943 | 946 | |
944 | 947 | /* |
945 | 948 | * Ok, the device is now all set up, we can |
drivers/scsi/scsi_sysfs.c
... | ... | @@ -771,6 +771,8 @@ |
771 | 771 | if (retval < 0) |
772 | 772 | return retval; |
773 | 773 | |
774 | + sdev->max_queue_depth = sdev->queue_depth; | |
775 | + | |
774 | 776 | return count; |
775 | 777 | } |
776 | 778 | |
... | ... | @@ -779,6 +781,37 @@ |
779 | 781 | sdev_store_queue_depth_rw); |
780 | 782 | |
781 | 783 | static ssize_t |
784 | +sdev_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 | + | |
794 | +static ssize_t | |
795 | +sdev_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 | + | |
809 | +static 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 | + | |
814 | +static ssize_t | |
782 | 815 | sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, |
783 | 816 | const char *buf, size_t count) |
784 | 817 | { |
... | ... | @@ -866,8 +899,12 @@ |
866 | 899 | } |
867 | 900 | |
868 | 901 | /* create queue files, which may be writable, depending on the host */ |
869 | - if (sdev->host->hostt->change_queue_depth) | |
870 | - error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); | |
902 | + if (sdev->host->hostt->change_queue_depth) { | |
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 | 908 | else |
872 | 909 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); |
873 | 910 | if (error) { |
include/scsi/scsi_device.h
... | ... | @@ -81,11 +81,14 @@ |
81 | 81 | struct list_head starved_entry; |
82 | 82 | struct scsi_cmnd *current_cmnd; /* currently active command */ |
83 | 83 | unsigned short queue_depth; /* How deep of a queue we want */ |
84 | + unsigned short max_queue_depth; /* max queue depth */ | |
84 | 85 | unsigned short last_queue_full_depth; /* These two are used by */ |
85 | 86 | unsigned short last_queue_full_count; /* scsi_track_queue_full() */ |
86 | - unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same | |
87 | - jiffie count on our counter, they | |
88 | - could all be from the same event. */ | |
87 | + unsigned long last_queue_full_time; /* last queue full time */ | |
88 | + unsigned long queue_ramp_up_period; /* ramp up period in jiffies */ | |
89 | +#define SCSI_DEFAULT_RAMP_UP_PERIOD (120 * HZ) | |
90 | + | |
91 | + unsigned long last_queue_ramp_up; /* last queue ramp up time */ | |
89 | 92 | |
90 | 93 | unsigned int id, lun, channel; |
91 | 94 |