aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
authorJames.Smart@Emulex.Com <James.Smart@Emulex.Com>2005-11-28 11:42:38 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2005-12-13 20:35:09 -0500
commit445cf4f4d2aa28f6ddd1d7a5f0986341ad61ec91 (patch)
tree4a26741b03835b44e266ce4799f4e35cc3800e6f /drivers/scsi/lpfc/lpfc_scsi.c
parent875fbdfe9b1b4c8f12622a8d8d81428ff0984875 (diff)
[SCSI] lpfc 8.1.1 : Added code to adjust lun queue depth to avoid target overloading
Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c422220db0ae..9ee8218404c0 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -409,6 +409,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
409 struct lpfc_rport_data *rdata = lpfc_cmd->rdata; 409 struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
410 struct lpfc_nodelist *pnode = rdata->pnode; 410 struct lpfc_nodelist *pnode = rdata->pnode;
411 struct scsi_cmnd *cmd = lpfc_cmd->pCmd; 411 struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
412 int result;
413 struct scsi_device *sdev, *tmp_sdev;
414 int depth = 0;
412 415
413 lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; 416 lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
414 lpfc_cmd->status = pIocbOut->iocb.ulpStatus; 417 lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
@@ -460,8 +463,63 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
460 *lp, *(lp + 3), cmd->retries, cmd->resid); 463 *lp, *(lp + 3), cmd->retries, cmd->resid);
461 } 464 }
462 465
466 result = cmd->result;
467 sdev = cmd->device;
463 cmd->scsi_done(cmd); 468 cmd->scsi_done(cmd);
464 469
470 if (!result &&
471 ((jiffies - pnode->last_ramp_up_time) >
472 LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
473 ((jiffies - pnode->last_q_full_time) >
474 LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
475 (phba->cfg_lun_queue_depth > sdev->queue_depth)) {
476 shost_for_each_device(tmp_sdev, sdev->host) {
477 if (phba->cfg_lun_queue_depth > tmp_sdev->queue_depth) {
478 if (tmp_sdev->id != sdev->id)
479 continue;
480 if (tmp_sdev->ordered_tags)
481 scsi_adjust_queue_depth(tmp_sdev,
482 MSG_ORDERED_TAG,
483 tmp_sdev->queue_depth+1);
484 else
485 scsi_adjust_queue_depth(tmp_sdev,
486 MSG_SIMPLE_TAG,
487 tmp_sdev->queue_depth+1);
488
489 pnode->last_ramp_up_time = jiffies;
490 }
491 }
492 }
493
494 /*
495 * Check for queue full. If the lun is reporting queue full, then
496 * back off the lun queue depth to prevent target overloads.
497 */
498 if (result == SAM_STAT_TASK_SET_FULL) {
499 pnode->last_q_full_time = jiffies;
500
501 shost_for_each_device(tmp_sdev, sdev->host) {
502 if (tmp_sdev->id != sdev->id)
503 continue;
504 depth = scsi_track_queue_full(tmp_sdev,
505 tmp_sdev->queue_depth - 1);
506 }
507 /*
508 * The queue depth cannot be lowered any more.
509 * Modify the returned error code to store
510 * the final depth value set by
511 * scsi_track_queue_full.
512 */
513 if (depth == -1)
514 depth = sdev->host->cmd_per_lun;
515
516 if (depth) {
517 lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
518 "%d:0711 detected queue full - lun queue depth "
519 " adjusted to %d.\n", phba->brd_no, depth);
520 }
521 }
522
465 lpfc_release_scsi_buf(phba, lpfc_cmd); 523 lpfc_release_scsi_buf(phba, lpfc_cmd);
466} 524}
467 525