aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/scsi/lpfc/lpfc.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c58
3 files changed, 62 insertions, 1 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 1f3873ae9d6..38ffa8d6e62 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -29,9 +29,10 @@ struct lpfc_sli2_slim;
29#define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */ 29#define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */
30#define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */ 30#define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */
31 31
32#define LPFC_CMD_PER_LUN 30 /* max outstanding cmds per lun */ 32#define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */
33#define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ 33#define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */
34#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ 34#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */
35#define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */
35 36
36/* Define macros for 64 bit support */ 37/* Define macros for 64 bit support */
37#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr))) 38#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr)))
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 084e7628ce1..ed6c81660e0 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -73,6 +73,8 @@ struct lpfc_nodelist {
73 struct lpfc_hba *nlp_phba; 73 struct lpfc_hba *nlp_phba;
74 struct lpfc_work_evt nodev_timeout_evt; 74 struct lpfc_work_evt nodev_timeout_evt;
75 struct lpfc_work_evt els_retry_evt; 75 struct lpfc_work_evt els_retry_evt;
76 unsigned long last_ramp_up_time; /* jiffy of last ramp up */
77 unsigned long last_q_full_time; /* jiffy of last queue full */
76}; 78};
77 79
78/* Defines for nlp_flag (uint32) */ 80/* Defines for nlp_flag (uint32) */
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c422220db0a..9ee8218404c 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