aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2017-05-15 18:20:41 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2017-05-16 21:18:41 -0400
commit61f3d4bf4f8f062cf6be143c9b7adbc3a017ea6e (patch)
treebed9f56d1f8805effdb0cd2d00614592bb1739eb
parent547077a44b3b49f56c0f05c0b46c8c617dea591d (diff)
scsi: lpfc: Fix nvmet RQ resource needs for large block writes.
Large block writes to the nvme target were failing because the default number of RQs posted was insufficient. Expand the NVMET RQs to 2048 RQEs and ensure a minimum of 512 RQEs are posted, no matter how many MRQs are configured. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c6
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c23
-rw-r--r--drivers/scsi/lpfc/lpfc_nvmet.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_nvmet.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c49
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h2
6 files changed, 31 insertions, 52 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 41ec7451689b..129d6cd7635b 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -60,9 +60,9 @@
60#define LPFC_MIN_DEVLOSS_TMO 1 60#define LPFC_MIN_DEVLOSS_TMO 1
61#define LPFC_MAX_DEVLOSS_TMO 255 61#define LPFC_MAX_DEVLOSS_TMO 255
62 62
63#define LPFC_DEF_MRQ_POST 256 63#define LPFC_DEF_MRQ_POST 512
64#define LPFC_MIN_MRQ_POST 32 64#define LPFC_MIN_MRQ_POST 512
65#define LPFC_MAX_MRQ_POST 512 65#define LPFC_MAX_MRQ_POST 2048
66 66
67/* 67/*
68 * Write key size should be multiple of 4. If write key is changed 68 * Write key size should be multiple of 4. If write key is changed
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index b1b181a756dc..5f62e3a1dff6 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -3390,6 +3390,11 @@ lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba)
3390 */ 3390 */
3391 els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); 3391 els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
3392 nvmet_xri_cnt = phba->cfg_nvmet_mrq * phba->cfg_nvmet_mrq_post; 3392 nvmet_xri_cnt = phba->cfg_nvmet_mrq * phba->cfg_nvmet_mrq_post;
3393
3394 /* Ensure we at least meet the minimun for the system */
3395 if (nvmet_xri_cnt < LPFC_NVMET_RQE_DEF_COUNT)
3396 nvmet_xri_cnt = LPFC_NVMET_RQE_DEF_COUNT;
3397
3393 tot_cnt = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt; 3398 tot_cnt = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
3394 if (nvmet_xri_cnt > tot_cnt) { 3399 if (nvmet_xri_cnt > tot_cnt) {
3395 phba->cfg_nvmet_mrq_post = tot_cnt / phba->cfg_nvmet_mrq; 3400 phba->cfg_nvmet_mrq_post = tot_cnt / phba->cfg_nvmet_mrq;
@@ -8158,7 +8163,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
8158 /* Create NVMET Receive Queue for header */ 8163 /* Create NVMET Receive Queue for header */
8159 qdesc = lpfc_sli4_queue_alloc(phba, 8164 qdesc = lpfc_sli4_queue_alloc(phba,
8160 phba->sli4_hba.rq_esize, 8165 phba->sli4_hba.rq_esize,
8161 phba->sli4_hba.rq_ecount); 8166 LPFC_NVMET_RQE_DEF_COUNT);
8162 if (!qdesc) { 8167 if (!qdesc) {
8163 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 8168 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
8164 "3146 Failed allocate " 8169 "3146 Failed allocate "
@@ -8180,7 +8185,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
8180 /* Create NVMET Receive Queue for data */ 8185 /* Create NVMET Receive Queue for data */
8181 qdesc = lpfc_sli4_queue_alloc(phba, 8186 qdesc = lpfc_sli4_queue_alloc(phba,
8182 phba->sli4_hba.rq_esize, 8187 phba->sli4_hba.rq_esize,
8183 phba->sli4_hba.rq_ecount); 8188 LPFC_NVMET_RQE_DEF_COUNT);
8184 if (!qdesc) { 8189 if (!qdesc) {
8185 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 8190 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
8186 "3156 Failed allocate " 8191 "3156 Failed allocate "
@@ -8770,9 +8775,6 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
8770 goto out_destroy; 8775 goto out_destroy;
8771 } 8776 }
8772 8777
8773 lpfc_rq_adjust_repost(phba, phba->sli4_hba.hdr_rq, LPFC_ELS_HBQ);
8774 lpfc_rq_adjust_repost(phba, phba->sli4_hba.dat_rq, LPFC_ELS_HBQ);
8775
8776 rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq, 8778 rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
8777 phba->sli4_hba.els_cq, LPFC_USOL); 8779 phba->sli4_hba.els_cq, LPFC_USOL);
8778 if (rc) { 8780 if (rc) {
@@ -11096,7 +11098,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
11096 struct lpfc_hba *phba; 11098 struct lpfc_hba *phba;
11097 struct lpfc_vport *vport = NULL; 11099 struct lpfc_vport *vport = NULL;
11098 struct Scsi_Host *shost = NULL; 11100 struct Scsi_Host *shost = NULL;
11099 int error, cnt; 11101 int error, cnt, num;
11100 uint32_t cfg_mode, intr_mode; 11102 uint32_t cfg_mode, intr_mode;
11101 11103
11102 /* Allocate memory for HBA structure */ 11104 /* Allocate memory for HBA structure */
@@ -11131,8 +11133,13 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
11131 } 11133 }
11132 11134
11133 cnt = phba->cfg_iocb_cnt * 1024; 11135 cnt = phba->cfg_iocb_cnt * 1024;
11134 if (phba->nvmet_support) 11136 if (phba->nvmet_support) {
11135 cnt += phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq; 11137 /* Ensure we at least meet the minimun for the system */
11138 num = (phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq);
11139 if (num < LPFC_NVMET_RQE_DEF_COUNT)
11140 num = LPFC_NVMET_RQE_DEF_COUNT;
11141 cnt += num;
11142 }
11136 11143
11137 /* Initialize and populate the iocb list per host */ 11144 /* Initialize and populate the iocb list per host */
11138 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 11145 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index bb12e2c9fbf4..dfa7296499cf 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -614,9 +614,9 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
614 lpfc_nvmeio_data(phba, "NVMET FCP CMND: xri x%x op x%x len x%x\n", 614 lpfc_nvmeio_data(phba, "NVMET FCP CMND: xri x%x op x%x len x%x\n",
615 ctxp->oxid, rsp->op, rsp->rsplen); 615 ctxp->oxid, rsp->op, rsp->rsplen);
616 616
617 ctxp->flag |= LPFC_NVMET_IO_INP;
617 rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq); 618 rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq);
618 if (rc == WQE_SUCCESS) { 619 if (rc == WQE_SUCCESS) {
619 ctxp->flag |= LPFC_NVMET_IO_INP;
620#ifdef CONFIG_SCSI_LPFC_DEBUG_FS 620#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
621 if (!phba->ktime_on) 621 if (!phba->ktime_on)
622 return 0; 622 return 0;
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.h b/drivers/scsi/lpfc/lpfc_nvmet.h
index 837210a3e7c8..55f2a859dc70 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.h
+++ b/drivers/scsi/lpfc/lpfc_nvmet.h
@@ -22,6 +22,7 @@
22 ********************************************************************/ 22 ********************************************************************/
23 23
24#define LPFC_NVMET_DEFAULT_SEGS (64 + 1) /* 256K IOs */ 24#define LPFC_NVMET_DEFAULT_SEGS (64 + 1) /* 256K IOs */
25#define LPFC_NVMET_RQE_DEF_COUNT 512
25#define LPFC_NVMET_SUCCESS_LEN 12 26#define LPFC_NVMET_SUCCESS_LEN 12
26 27
27/* Used for NVME Target */ 28/* Used for NVME Target */
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 333c5094b97d..f344abce4949 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -479,22 +479,23 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
479 if (unlikely(!hq) || unlikely(!dq)) 479 if (unlikely(!hq) || unlikely(!dq))
480 return -ENOMEM; 480 return -ENOMEM;
481 put_index = hq->host_index; 481 put_index = hq->host_index;
482 temp_hrqe = hq->qe[hq->host_index].rqe; 482 temp_hrqe = hq->qe[put_index].rqe;
483 temp_drqe = dq->qe[dq->host_index].rqe; 483 temp_drqe = dq->qe[dq->host_index].rqe;
484 484
485 if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ) 485 if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ)
486 return -EINVAL; 486 return -EINVAL;
487 if (hq->host_index != dq->host_index) 487 if (put_index != dq->host_index)
488 return -EINVAL; 488 return -EINVAL;
489 /* If the host has not yet processed the next entry then we are done */ 489 /* If the host has not yet processed the next entry then we are done */
490 if (((hq->host_index + 1) % hq->entry_count) == hq->hba_index) 490 if (((put_index + 1) % hq->entry_count) == hq->hba_index)
491 return -EBUSY; 491 return -EBUSY;
492 lpfc_sli_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size); 492 lpfc_sli_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size);
493 lpfc_sli_pcimem_bcopy(drqe, temp_drqe, dq->entry_size); 493 lpfc_sli_pcimem_bcopy(drqe, temp_drqe, dq->entry_size);
494 494
495 /* Update the host index to point to the next slot */ 495 /* Update the host index to point to the next slot */
496 hq->host_index = ((hq->host_index + 1) % hq->entry_count); 496 hq->host_index = ((put_index + 1) % hq->entry_count);
497 dq->host_index = ((dq->host_index + 1) % dq->entry_count); 497 dq->host_index = ((dq->host_index + 1) % dq->entry_count);
498 hq->RQ_buf_posted++;
498 499
499 /* Ring The Header Receive Queue Doorbell */ 500 /* Ring The Header Receive Queue Doorbell */
500 if (!(hq->host_index % hq->entry_repost)) { 501 if (!(hq->host_index % hq->entry_repost)) {
@@ -512,7 +513,6 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
512 } else { 513 } else {
513 return -EINVAL; 514 return -EINVAL;
514 } 515 }
515 hq->RQ_buf_posted += hq->entry_repost;
516 writel(doorbell.word0, hq->db_regaddr); 516 writel(doorbell.word0, hq->db_regaddr);
517 } 517 }
518 return put_index; 518 return put_index;
@@ -6905,14 +6905,9 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
6905 INIT_LIST_HEAD(&rqbp->rqb_buffer_list); 6905 INIT_LIST_HEAD(&rqbp->rqb_buffer_list);
6906 rqbp->rqb_alloc_buffer = lpfc_sli4_nvmet_alloc; 6906 rqbp->rqb_alloc_buffer = lpfc_sli4_nvmet_alloc;
6907 rqbp->rqb_free_buffer = lpfc_sli4_nvmet_free; 6907 rqbp->rqb_free_buffer = lpfc_sli4_nvmet_free;
6908 rqbp->entry_count = 256; 6908 rqbp->entry_count = LPFC_NVMET_RQE_DEF_COUNT;
6909 rqbp->buffer_count = 0; 6909 rqbp->buffer_count = 0;
6910 6910
6911 /* Divide by 4 and round down to multiple of 16 */
6912 rc = (phba->cfg_nvmet_mrq_post >> 2) & 0xfff8;
6913 phba->sli4_hba.nvmet_mrq_hdr[i]->entry_repost = rc;
6914 phba->sli4_hba.nvmet_mrq_data[i]->entry_repost = rc;
6915
6916 lpfc_post_rq_buffer( 6911 lpfc_post_rq_buffer(
6917 phba, phba->sli4_hba.nvmet_mrq_hdr[i], 6912 phba, phba->sli4_hba.nvmet_mrq_hdr[i],
6918 phba->sli4_hba.nvmet_mrq_data[i], 6913 phba->sli4_hba.nvmet_mrq_data[i],
@@ -14893,34 +14888,6 @@ out:
14893} 14888}
14894 14889
14895/** 14890/**
14896 * lpfc_rq_adjust_repost - Adjust entry_repost for an RQ
14897 * @phba: HBA structure that indicates port to create a queue on.
14898 * @rq: The queue structure to use for the receive queue.
14899 * @qno: The associated HBQ number
14900 *
14901 *
14902 * For SLI4 we need to adjust the RQ repost value based on
14903 * the number of buffers that are initially posted to the RQ.
14904 */
14905void
14906lpfc_rq_adjust_repost(struct lpfc_hba *phba, struct lpfc_queue *rq, int qno)
14907{
14908 uint32_t cnt;
14909
14910 /* sanity check on queue memory */
14911 if (!rq)
14912 return;
14913 cnt = lpfc_hbq_defs[qno]->entry_count;
14914
14915 /* Recalc repost for RQs based on buffers initially posted */
14916 cnt = (cnt >> 3);
14917 if (cnt < LPFC_QUEUE_MIN_REPOST)
14918 cnt = LPFC_QUEUE_MIN_REPOST;
14919
14920 rq->entry_repost = cnt;
14921}
14922
14923/**
14924 * lpfc_rq_create - Create a Receive Queue on the HBA 14891 * lpfc_rq_create - Create a Receive Queue on the HBA
14925 * @phba: HBA structure that indicates port to create a queue on. 14892 * @phba: HBA structure that indicates port to create a queue on.
14926 * @hrq: The queue structure to use to create the header receive queue. 14893 * @hrq: The queue structure to use to create the header receive queue.
@@ -15105,6 +15072,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
15105 hrq->subtype = subtype; 15072 hrq->subtype = subtype;
15106 hrq->host_index = 0; 15073 hrq->host_index = 0;
15107 hrq->hba_index = 0; 15074 hrq->hba_index = 0;
15075 hrq->entry_repost = LPFC_RQ_REPOST;
15108 15076
15109 /* now create the data queue */ 15077 /* now create the data queue */
15110 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE, 15078 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
@@ -15186,6 +15154,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
15186 drq->subtype = subtype; 15154 drq->subtype = subtype;
15187 drq->host_index = 0; 15155 drq->host_index = 0;
15188 drq->hba_index = 0; 15156 drq->hba_index = 0;
15157 drq->entry_repost = LPFC_RQ_REPOST;
15189 15158
15190 /* link the header and data RQs onto the parent cq child list */ 15159 /* link the header and data RQs onto the parent cq child list */
15191 list_add_tail(&hrq->list, &cq->child_list); 15160 list_add_tail(&hrq->list, &cq->child_list);
@@ -15343,6 +15312,7 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
15343 hrq->subtype = subtype; 15312 hrq->subtype = subtype;
15344 hrq->host_index = 0; 15313 hrq->host_index = 0;
15345 hrq->hba_index = 0; 15314 hrq->hba_index = 0;
15315 hrq->entry_repost = LPFC_RQ_REPOST;
15346 15316
15347 drq->db_format = LPFC_DB_RING_FORMAT; 15317 drq->db_format = LPFC_DB_RING_FORMAT;
15348 drq->db_regaddr = phba->sli4_hba.RQDBregaddr; 15318 drq->db_regaddr = phba->sli4_hba.RQDBregaddr;
@@ -15351,6 +15321,7 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
15351 drq->subtype = subtype; 15321 drq->subtype = subtype;
15352 drq->host_index = 0; 15322 drq->host_index = 0;
15353 drq->hba_index = 0; 15323 drq->hba_index = 0;
15324 drq->entry_repost = LPFC_RQ_REPOST;
15354 15325
15355 list_add_tail(&hrq->list, &cq->child_list); 15326 list_add_tail(&hrq->list, &cq->child_list);
15356 list_add_tail(&drq->list, &cq->child_list); 15327 list_add_tail(&drq->list, &cq->child_list);
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 7a8cbeb6a745..422bde85c9f1 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -156,6 +156,7 @@ struct lpfc_queue {
156 uint32_t entry_size; /* Size of each queue entry. */ 156 uint32_t entry_size; /* Size of each queue entry. */
157 uint32_t entry_repost; /* Count of entries before doorbell is rung */ 157 uint32_t entry_repost; /* Count of entries before doorbell is rung */
158#define LPFC_QUEUE_MIN_REPOST 8 158#define LPFC_QUEUE_MIN_REPOST 8
159#define LPFC_RQ_REPOST 64
159 uint32_t queue_id; /* Queue ID assigned by the hardware */ 160 uint32_t queue_id; /* Queue ID assigned by the hardware */
160 uint32_t assoc_qid; /* Queue ID associated with, for CQ/WQ/MQ */ 161 uint32_t assoc_qid; /* Queue ID associated with, for CQ/WQ/MQ */
161 uint32_t page_count; /* Number of pages allocated for this queue */ 162 uint32_t page_count; /* Number of pages allocated for this queue */
@@ -763,7 +764,6 @@ int lpfc_rq_create(struct lpfc_hba *, struct lpfc_queue *,
763int lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp, 764int lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
764 struct lpfc_queue **drqp, struct lpfc_queue **cqp, 765 struct lpfc_queue **drqp, struct lpfc_queue **cqp,
765 uint32_t subtype); 766 uint32_t subtype);
766void lpfc_rq_adjust_repost(struct lpfc_hba *, struct lpfc_queue *, int);
767int lpfc_eq_destroy(struct lpfc_hba *, struct lpfc_queue *); 767int lpfc_eq_destroy(struct lpfc_hba *, struct lpfc_queue *);
768int lpfc_cq_destroy(struct lpfc_hba *, struct lpfc_queue *); 768int lpfc_cq_destroy(struct lpfc_hba *, struct lpfc_queue *);
769int lpfc_mq_destroy(struct lpfc_hba *, struct lpfc_queue *); 769int lpfc_mq_destroy(struct lpfc_hba *, struct lpfc_queue *);