diff options
author | Vasu Dev <vasu.dev@intel.com> | 2009-10-22 18:46:33 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:00:44 -0500 |
commit | 4a84067dbfce436b81779e585bf712b02ceee552 (patch) | |
tree | f787d413a11c6564ad4440d0a245f56d0e6b73bf /drivers/scsi/scsi_error.c | |
parent | 14caf44c69184ed72d46a2f883311daf27a4192f (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/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 38 |
1 files changed, 38 insertions, 0 deletions
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 | ||
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 | static void scsi_handle_queue_full(struct scsi_device *sdev) | 370 | static 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: |