[SCSI] lpfc 8.3.15: Add target queue depth throttling
authorJames Smart <james.smart@emulex.com>
Wed, 14 Jul 2010 19:32:10 +0000 (15:32 -0400)
committerJames Bottomley <James.Bottomley@suse.de>
Wed, 28 Jul 2010 14:05:41 +0000 (09:05 -0500)
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>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_scsi.c

index bb40fcbe17c5739f198f94813d54ecdbe8e79091..3482d5a5aed21ada9e3adc8b58e125c6c7a01b4d 100644 (file)
@@ -48,7 +48,7 @@ struct lpfc_sli2_slim;
 #define LPFC_TGTQ_INTERVAL     40000   /* Min amount of time between tgt
                                           queue depth change in millisecs */
 #define LPFC_TGTQ_RAMPUP_PCENT 5       /* Target queue rampup in percentage */
-#define LPFC_MIN_TGT_QDEPTH    100
+#define LPFC_MIN_TGT_QDEPTH    10
 #define LPFC_MAX_TGT_QDEPTH    0xFFFF
 
 #define  LPFC_MAX_BUCKET_COUNT 20      /* Maximum no. of buckets for stat data
@@ -400,6 +400,7 @@ struct lpfc_vport {
        uint32_t cfg_max_luns;
        uint32_t cfg_enable_da_id;
        uint32_t cfg_max_scsicmpl_time;
+       uint32_t cfg_tgt_queue_depth;
 
        uint32_t dev_loss_tmo_changed;
 
index a7c6b7390554f425da014f31d1fb69efe1592c99..868874c28f99a6c0bf3ab89d0419f0698eff032d 100644 (file)
@@ -2207,6 +2207,13 @@ LPFC_VPORT_ATTR_R(enable_da_id, 0, 0, 1,
 LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 128,
                  "Max number of FCP commands we can queue to a specific LUN");
 
+/*
+# tgt_queue_depth:  This parameter is used to limit the number of outstanding
+# commands per target port. Value range is [10,65535]. Default value is 65535.
+*/
+LPFC_VPORT_ATTR_R(tgt_queue_depth, 65535, 10, 65535,
+       "Max number of FCP commands we can queue to a specific target port");
+
 /*
 # hba_queue_depth:  This parameter is used to limit the number of outstanding
 # commands per lpfc HBA. Value range is [32,8192]. If this parameter
@@ -3122,7 +3129,7 @@ lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
                        continue;
                if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
                        continue;
-               ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
+               ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
        }
        spin_unlock_irq(shost->host_lock);
        return 0;
@@ -3326,6 +3333,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
        &dev_attr_lpfc_temp_sensor,
        &dev_attr_lpfc_log_verbose,
        &dev_attr_lpfc_lun_queue_depth,
+       &dev_attr_lpfc_tgt_queue_depth,
        &dev_attr_lpfc_hba_queue_depth,
        &dev_attr_lpfc_peer_port_login,
        &dev_attr_lpfc_nodev_tmo,
@@ -3387,6 +3395,7 @@ struct device_attribute *lpfc_vport_attrs[] = {
        &dev_attr_lpfc_drvr_version,
        &dev_attr_lpfc_log_verbose,
        &dev_attr_lpfc_lun_queue_depth,
+       &dev_attr_lpfc_tgt_queue_depth,
        &dev_attr_lpfc_nodev_tmo,
        &dev_attr_lpfc_devloss_tmo,
        &dev_attr_lpfc_hba_queue_depth,
@@ -4575,6 +4584,7 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
 {
        lpfc_log_verbose_init(vport, lpfc_log_verbose);
        lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
+       lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth);
        lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
        lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
        lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
index 92498e488f4f4c331343d53e4b7fc2c85c723504..0639c994349c55be5936a38852cbb23acabdb357 100644 (file)
@@ -3583,7 +3583,7 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        kref_init(&ndlp->kref);
        NLP_INT_NODE_ACT(ndlp);
        atomic_set(&ndlp->cmd_pending, 0);
-       ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
+       ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
 }
 
 struct lpfc_nodelist *
index d6089c985c3f4a7045ab33076e7d37a4a4f81571..c818a7255962845ac258462545cd6ac6b70c9133 100644 (file)
@@ -2458,14 +2458,16 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
                }
                spin_unlock_irqrestore(shost->host_lock, flags);
        } else if (pnode && NLP_CHK_NODE_ACT(pnode)) {
-               if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) &&
+               if ((pnode->cmd_qdepth < vport->cfg_tgt_queue_depth) &&
                   time_after(jiffies, pnode->last_change_time +
                              msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) {
                        spin_lock_irqsave(shost->host_lock, flags);
-                       pnode->cmd_qdepth += pnode->cmd_qdepth *
-                               LPFC_TGTQ_RAMPUP_PCENT / 100;
-                       if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH)
-                               pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
+                       depth = pnode->cmd_qdepth * LPFC_TGTQ_RAMPUP_PCENT
+                               / 100;
+                       depth = depth ? depth : 1;
+                       pnode->cmd_qdepth += depth;
+                       if (pnode->cmd_qdepth > vport->cfg_tgt_queue_depth)
+                               pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
                        pnode->last_change_time = jiffies;
                        spin_unlock_irqrestore(shost->host_lock, flags);
                }
@@ -2920,8 +2922,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
                cmnd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0);
                goto out_fail_command;
        }
-       if (vport->cfg_max_scsicmpl_time &&
-               (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth))
+       if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
                goto out_host_busy;
 
        lpfc_cmd = lpfc_get_scsi_buf(phba);