diff options
author | James Smart <james.smart@emulex.com> | 2010-07-14 15:32:10 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-28 10:05:41 -0400 |
commit | 7dc517df3ace15b5a29b331abe0af86ed4836236 (patch) | |
tree | 7f95a4b9833b1549078244c28d4ddcde56d847ed /drivers/scsi/lpfc | |
parent | 3804dc84b8c11038ef75d97fd11e43658f623665 (diff) |
[SCSI] lpfc 8.3.15: Add target queue depth throttling
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 12 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 15 |
4 files changed, 22 insertions, 10 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index bb40fcbe17c5..3482d5a5aed2 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -48,7 +48,7 @@ struct lpfc_sli2_slim; | |||
48 | #define LPFC_TGTQ_INTERVAL 40000 /* Min amount of time between tgt | 48 | #define LPFC_TGTQ_INTERVAL 40000 /* Min amount of time between tgt |
49 | queue depth change in millisecs */ | 49 | queue depth change in millisecs */ |
50 | #define LPFC_TGTQ_RAMPUP_PCENT 5 /* Target queue rampup in percentage */ | 50 | #define LPFC_TGTQ_RAMPUP_PCENT 5 /* Target queue rampup in percentage */ |
51 | #define LPFC_MIN_TGT_QDEPTH 100 | 51 | #define LPFC_MIN_TGT_QDEPTH 10 |
52 | #define LPFC_MAX_TGT_QDEPTH 0xFFFF | 52 | #define LPFC_MAX_TGT_QDEPTH 0xFFFF |
53 | 53 | ||
54 | #define LPFC_MAX_BUCKET_COUNT 20 /* Maximum no. of buckets for stat data | 54 | #define LPFC_MAX_BUCKET_COUNT 20 /* Maximum no. of buckets for stat data |
@@ -400,6 +400,7 @@ struct lpfc_vport { | |||
400 | uint32_t cfg_max_luns; | 400 | uint32_t cfg_max_luns; |
401 | uint32_t cfg_enable_da_id; | 401 | uint32_t cfg_enable_da_id; |
402 | uint32_t cfg_max_scsicmpl_time; | 402 | uint32_t cfg_max_scsicmpl_time; |
403 | uint32_t cfg_tgt_queue_depth; | ||
403 | 404 | ||
404 | uint32_t dev_loss_tmo_changed; | 405 | uint32_t dev_loss_tmo_changed; |
405 | 406 | ||
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index a7c6b7390554..868874c28f99 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -2208,6 +2208,13 @@ LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 128, | |||
2208 | "Max number of FCP commands we can queue to a specific LUN"); | 2208 | "Max number of FCP commands we can queue to a specific LUN"); |
2209 | 2209 | ||
2210 | /* | 2210 | /* |
2211 | # tgt_queue_depth: This parameter is used to limit the number of outstanding | ||
2212 | # commands per target port. Value range is [10,65535]. Default value is 65535. | ||
2213 | */ | ||
2214 | LPFC_VPORT_ATTR_R(tgt_queue_depth, 65535, 10, 65535, | ||
2215 | "Max number of FCP commands we can queue to a specific target port"); | ||
2216 | |||
2217 | /* | ||
2211 | # hba_queue_depth: This parameter is used to limit the number of outstanding | 2218 | # hba_queue_depth: This parameter is used to limit the number of outstanding |
2212 | # commands per lpfc HBA. Value range is [32,8192]. If this parameter | 2219 | # commands per lpfc HBA. Value range is [32,8192]. If this parameter |
2213 | # value is greater than the maximum number of exchanges supported by the HBA, | 2220 | # value is greater than the maximum number of exchanges supported by the HBA, |
@@ -3122,7 +3129,7 @@ lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val) | |||
3122 | continue; | 3129 | continue; |
3123 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 3130 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
3124 | continue; | 3131 | continue; |
3125 | ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; | 3132 | ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth; |
3126 | } | 3133 | } |
3127 | spin_unlock_irq(shost->host_lock); | 3134 | spin_unlock_irq(shost->host_lock); |
3128 | return 0; | 3135 | return 0; |
@@ -3326,6 +3333,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
3326 | &dev_attr_lpfc_temp_sensor, | 3333 | &dev_attr_lpfc_temp_sensor, |
3327 | &dev_attr_lpfc_log_verbose, | 3334 | &dev_attr_lpfc_log_verbose, |
3328 | &dev_attr_lpfc_lun_queue_depth, | 3335 | &dev_attr_lpfc_lun_queue_depth, |
3336 | &dev_attr_lpfc_tgt_queue_depth, | ||
3329 | &dev_attr_lpfc_hba_queue_depth, | 3337 | &dev_attr_lpfc_hba_queue_depth, |
3330 | &dev_attr_lpfc_peer_port_login, | 3338 | &dev_attr_lpfc_peer_port_login, |
3331 | &dev_attr_lpfc_nodev_tmo, | 3339 | &dev_attr_lpfc_nodev_tmo, |
@@ -3387,6 +3395,7 @@ struct device_attribute *lpfc_vport_attrs[] = { | |||
3387 | &dev_attr_lpfc_drvr_version, | 3395 | &dev_attr_lpfc_drvr_version, |
3388 | &dev_attr_lpfc_log_verbose, | 3396 | &dev_attr_lpfc_log_verbose, |
3389 | &dev_attr_lpfc_lun_queue_depth, | 3397 | &dev_attr_lpfc_lun_queue_depth, |
3398 | &dev_attr_lpfc_tgt_queue_depth, | ||
3390 | &dev_attr_lpfc_nodev_tmo, | 3399 | &dev_attr_lpfc_nodev_tmo, |
3391 | &dev_attr_lpfc_devloss_tmo, | 3400 | &dev_attr_lpfc_devloss_tmo, |
3392 | &dev_attr_lpfc_hba_queue_depth, | 3401 | &dev_attr_lpfc_hba_queue_depth, |
@@ -4575,6 +4584,7 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport) | |||
4575 | { | 4584 | { |
4576 | lpfc_log_verbose_init(vport, lpfc_log_verbose); | 4585 | lpfc_log_verbose_init(vport, lpfc_log_verbose); |
4577 | lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth); | 4586 | lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth); |
4587 | lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth); | ||
4578 | lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo); | 4588 | lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo); |
4579 | lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo); | 4589 | lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo); |
4580 | lpfc_peer_port_login_init(vport, lpfc_peer_port_login); | 4590 | lpfc_peer_port_login_init(vport, lpfc_peer_port_login); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 92498e488f4f..0639c994349c 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -3583,7 +3583,7 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
3583 | kref_init(&ndlp->kref); | 3583 | kref_init(&ndlp->kref); |
3584 | NLP_INT_NODE_ACT(ndlp); | 3584 | NLP_INT_NODE_ACT(ndlp); |
3585 | atomic_set(&ndlp->cmd_pending, 0); | 3585 | atomic_set(&ndlp->cmd_pending, 0); |
3586 | ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; | 3586 | ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth; |
3587 | } | 3587 | } |
3588 | 3588 | ||
3589 | struct lpfc_nodelist * | 3589 | struct lpfc_nodelist * |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index d6089c985c3f..c818a7255962 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -2458,14 +2458,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
2458 | } | 2458 | } |
2459 | spin_unlock_irqrestore(shost->host_lock, flags); | 2459 | spin_unlock_irqrestore(shost->host_lock, flags); |
2460 | } else if (pnode && NLP_CHK_NODE_ACT(pnode)) { | 2460 | } else if (pnode && NLP_CHK_NODE_ACT(pnode)) { |
2461 | if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) && | 2461 | if ((pnode->cmd_qdepth < vport->cfg_tgt_queue_depth) && |
2462 | time_after(jiffies, pnode->last_change_time + | 2462 | time_after(jiffies, pnode->last_change_time + |
2463 | msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) { | 2463 | msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) { |
2464 | spin_lock_irqsave(shost->host_lock, flags); | 2464 | spin_lock_irqsave(shost->host_lock, flags); |
2465 | pnode->cmd_qdepth += pnode->cmd_qdepth * | 2465 | depth = pnode->cmd_qdepth * LPFC_TGTQ_RAMPUP_PCENT |
2466 | LPFC_TGTQ_RAMPUP_PCENT / 100; | 2466 | / 100; |
2467 | if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH) | 2467 | depth = depth ? depth : 1; |
2468 | pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; | 2468 | pnode->cmd_qdepth += depth; |
2469 | if (pnode->cmd_qdepth > vport->cfg_tgt_queue_depth) | ||
2470 | pnode->cmd_qdepth = vport->cfg_tgt_queue_depth; | ||
2469 | pnode->last_change_time = jiffies; | 2471 | pnode->last_change_time = jiffies; |
2470 | spin_unlock_irqrestore(shost->host_lock, flags); | 2472 | spin_unlock_irqrestore(shost->host_lock, flags); |
2471 | } | 2473 | } |
@@ -2920,8 +2922,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
2920 | cmnd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0); | 2922 | cmnd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0); |
2921 | goto out_fail_command; | 2923 | goto out_fail_command; |
2922 | } | 2924 | } |
2923 | if (vport->cfg_max_scsicmpl_time && | 2925 | if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth) |
2924 | (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)) | ||
2925 | goto out_host_busy; | 2926 | goto out_host_busy; |
2926 | 2927 | ||
2927 | lpfc_cmd = lpfc_get_scsi_buf(phba); | 2928 | lpfc_cmd = lpfc_get_scsi_buf(phba); |