aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-07-14 15:32:10 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:05:41 -0400
commit7dc517df3ace15b5a29b331abe0af86ed4836236 (patch)
tree7f95a4b9833b1549078244c28d4ddcde56d847ed /drivers/scsi/lpfc
parent3804dc84b8c11038ef75d97fd11e43658f623665 (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.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c15
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*/
2214LPFC_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
3589struct lpfc_nodelist * 3589struct 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);