scsi: lpfc: Fix nvmet RQ resource needs for large block writes.
authorJames Smart <jsmart2021@gmail.com>
Mon, 15 May 2017 22:20:41 +0000 (15:20 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 17 May 2017 01:18:41 +0000 (21:18 -0400)
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>
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/lpfc/lpfc_nvmet.h
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli4.h

index 41ec7451689b204d4a7ccd597aaa4ef70eaade47..129d6cd7635bd9ef73d2568d4c092f4ca63a033b 100644 (file)
@@ -60,9 +60,9 @@
 #define LPFC_MIN_DEVLOSS_TMO   1
 #define LPFC_MAX_DEVLOSS_TMO   255
 
-#define LPFC_DEF_MRQ_POST      256
-#define LPFC_MIN_MRQ_POST      32
-#define LPFC_MAX_MRQ_POST      512
+#define LPFC_DEF_MRQ_POST      512
+#define LPFC_MIN_MRQ_POST      512
+#define LPFC_MAX_MRQ_POST      2048
 
 /*
  * Write key size should be multiple of 4. If write key is changed
index b1b181a756dc67f68ed61a9cf9d0e7a60b98cdcb..5f62e3a1dff60658989513101809fb620000ba8b 100644 (file)
@@ -3390,6 +3390,11 @@ lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba)
         */
        els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
        nvmet_xri_cnt = phba->cfg_nvmet_mrq * phba->cfg_nvmet_mrq_post;
+
+       /* Ensure we at least meet the minimun for the system */
+       if (nvmet_xri_cnt < LPFC_NVMET_RQE_DEF_COUNT)
+               nvmet_xri_cnt = LPFC_NVMET_RQE_DEF_COUNT;
+
        tot_cnt = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
        if (nvmet_xri_cnt > tot_cnt) {
                phba->cfg_nvmet_mrq_post = tot_cnt / phba->cfg_nvmet_mrq;
@@ -8158,7 +8163,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
                        /* Create NVMET Receive Queue for header */
                        qdesc = lpfc_sli4_queue_alloc(phba,
                                                      phba->sli4_hba.rq_esize,
-                                                     phba->sli4_hba.rq_ecount);
+                                                     LPFC_NVMET_RQE_DEF_COUNT);
                        if (!qdesc) {
                                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                                "3146 Failed allocate "
@@ -8180,7 +8185,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
                        /* Create NVMET Receive Queue for data */
                        qdesc = lpfc_sli4_queue_alloc(phba,
                                                      phba->sli4_hba.rq_esize,
-                                                     phba->sli4_hba.rq_ecount);
+                                                     LPFC_NVMET_RQE_DEF_COUNT);
                        if (!qdesc) {
                                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
                                                "3156 Failed allocate "
@@ -8770,9 +8775,6 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
                goto out_destroy;
        }
 
-       lpfc_rq_adjust_repost(phba, phba->sli4_hba.hdr_rq, LPFC_ELS_HBQ);
-       lpfc_rq_adjust_repost(phba, phba->sli4_hba.dat_rq, LPFC_ELS_HBQ);
-
        rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
                            phba->sli4_hba.els_cq, LPFC_USOL);
        if (rc) {
@@ -11096,7 +11098,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
        struct lpfc_hba   *phba;
        struct lpfc_vport *vport = NULL;
        struct Scsi_Host  *shost = NULL;
-       int error, cnt;
+       int error, cnt, num;
        uint32_t cfg_mode, intr_mode;
 
        /* Allocate memory for HBA structure */
@@ -11131,8 +11133,13 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
        }
 
        cnt = phba->cfg_iocb_cnt * 1024;
-       if (phba->nvmet_support)
-               cnt += phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq;
+       if (phba->nvmet_support) {
+               /* Ensure we at least meet the minimun for the system */
+               num = (phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq);
+               if (num < LPFC_NVMET_RQE_DEF_COUNT)
+                       num = LPFC_NVMET_RQE_DEF_COUNT;
+               cnt += num;
+       }
 
        /* Initialize and populate the iocb list per host */
        lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
index bb12e2c9fbf4e43f68b762b89cf265582bae154b..dfa7296499cfd16d92c84c4fcd7326b75dad6dc4 100644 (file)
@@ -614,9 +614,9 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
        lpfc_nvmeio_data(phba, "NVMET FCP CMND: xri x%x op x%x len x%x\n",
                         ctxp->oxid, rsp->op, rsp->rsplen);
 
+       ctxp->flag |= LPFC_NVMET_IO_INP;
        rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq);
        if (rc == WQE_SUCCESS) {
-               ctxp->flag |= LPFC_NVMET_IO_INP;
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
                if (!phba->ktime_on)
                        return 0;
index 837210a3e7c819bdd91e90b074917ff351da938e..55f2a859dc70ed3e0ec4b42d9b844e04dfa9affb 100644 (file)
@@ -22,6 +22,7 @@
  ********************************************************************/
 
 #define LPFC_NVMET_DEFAULT_SEGS                (64 + 1)        /* 256K IOs */
+#define LPFC_NVMET_RQE_DEF_COUNT       512
 #define LPFC_NVMET_SUCCESS_LEN 12
 
 /* Used for NVME Target */
index 333c5094b97dd7001b36e66efca2c5362d8b916e..f344abce494986c8400ce209eb659461c8044cc3 100644 (file)
@@ -479,22 +479,23 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
        if (unlikely(!hq) || unlikely(!dq))
                return -ENOMEM;
        put_index = hq->host_index;
-       temp_hrqe = hq->qe[hq->host_index].rqe;
+       temp_hrqe = hq->qe[put_index].rqe;
        temp_drqe = dq->qe[dq->host_index].rqe;
 
        if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ)
                return -EINVAL;
-       if (hq->host_index != dq->host_index)
+       if (put_index != dq->host_index)
                return -EINVAL;
        /* If the host has not yet processed the next entry then we are done */
-       if (((hq->host_index + 1) % hq->entry_count) == hq->hba_index)
+       if (((put_index + 1) % hq->entry_count) == hq->hba_index)
                return -EBUSY;
        lpfc_sli_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size);
        lpfc_sli_pcimem_bcopy(drqe, temp_drqe, dq->entry_size);
 
        /* Update the host index to point to the next slot */
-       hq->host_index = ((hq->host_index + 1) % hq->entry_count);
+       hq->host_index = ((put_index + 1) % hq->entry_count);
        dq->host_index = ((dq->host_index + 1) % dq->entry_count);
+       hq->RQ_buf_posted++;
 
        /* Ring The Header Receive Queue Doorbell */
        if (!(hq->host_index % hq->entry_repost)) {
@@ -512,7 +513,6 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
                } else {
                        return -EINVAL;
                }
-               hq->RQ_buf_posted += hq->entry_repost;
                writel(doorbell.word0, hq->db_regaddr);
        }
        return put_index;
@@ -6905,14 +6905,9 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                        INIT_LIST_HEAD(&rqbp->rqb_buffer_list);
                        rqbp->rqb_alloc_buffer = lpfc_sli4_nvmet_alloc;
                        rqbp->rqb_free_buffer = lpfc_sli4_nvmet_free;
-                       rqbp->entry_count = 256;
+                       rqbp->entry_count = LPFC_NVMET_RQE_DEF_COUNT;
                        rqbp->buffer_count = 0;
 
-                       /* Divide by 4 and round down to multiple of 16 */
-                       rc = (phba->cfg_nvmet_mrq_post >> 2) & 0xfff8;
-                       phba->sli4_hba.nvmet_mrq_hdr[i]->entry_repost = rc;
-                       phba->sli4_hba.nvmet_mrq_data[i]->entry_repost = rc;
-
                        lpfc_post_rq_buffer(
                                phba, phba->sli4_hba.nvmet_mrq_hdr[i],
                                phba->sli4_hba.nvmet_mrq_data[i],
@@ -14892,34 +14887,6 @@ out:
        return status;
 }
 
-/**
- * lpfc_rq_adjust_repost - Adjust entry_repost for an RQ
- * @phba: HBA structure that indicates port to create a queue on.
- * @rq:   The queue structure to use for the receive queue.
- * @qno:  The associated HBQ number
- *
- *
- * For SLI4 we need to adjust the RQ repost value based on
- * the number of buffers that are initially posted to the RQ.
- */
-void
-lpfc_rq_adjust_repost(struct lpfc_hba *phba, struct lpfc_queue *rq, int qno)
-{
-       uint32_t cnt;
-
-       /* sanity check on queue memory */
-       if (!rq)
-               return;
-       cnt = lpfc_hbq_defs[qno]->entry_count;
-
-       /* Recalc repost for RQs based on buffers initially posted */
-       cnt = (cnt >> 3);
-       if (cnt < LPFC_QUEUE_MIN_REPOST)
-               cnt = LPFC_QUEUE_MIN_REPOST;
-
-       rq->entry_repost = cnt;
-}
-
 /**
  * lpfc_rq_create - Create a Receive Queue on the HBA
  * @phba: HBA structure that indicates port to create a queue on.
@@ -15105,6 +15072,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
        hrq->subtype = subtype;
        hrq->host_index = 0;
        hrq->hba_index = 0;
+       hrq->entry_repost = LPFC_RQ_REPOST;
 
        /* now create the data queue */
        lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
@@ -15186,6 +15154,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
        drq->subtype = subtype;
        drq->host_index = 0;
        drq->hba_index = 0;
+       drq->entry_repost = LPFC_RQ_REPOST;
 
        /* link the header and data RQs onto the parent cq child list */
        list_add_tail(&hrq->list, &cq->child_list);
@@ -15343,6 +15312,7 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
                hrq->subtype = subtype;
                hrq->host_index = 0;
                hrq->hba_index = 0;
+               hrq->entry_repost = LPFC_RQ_REPOST;
 
                drq->db_format = LPFC_DB_RING_FORMAT;
                drq->db_regaddr = phba->sli4_hba.RQDBregaddr;
@@ -15351,6 +15321,7 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
                drq->subtype = subtype;
                drq->host_index = 0;
                drq->hba_index = 0;
+               drq->entry_repost = LPFC_RQ_REPOST;
 
                list_add_tail(&hrq->list, &cq->child_list);
                list_add_tail(&drq->list, &cq->child_list);
index 7a8cbeb6a7454747bb3e61204849487a3e40a793..422bde85c9f1cc26f0c951a0ed7fbb3ed825b866 100644 (file)
@@ -156,6 +156,7 @@ struct lpfc_queue {
        uint32_t entry_size;    /* Size of each queue entry. */
        uint32_t entry_repost;  /* Count of entries before doorbell is rung */
 #define LPFC_QUEUE_MIN_REPOST  8
+#define LPFC_RQ_REPOST         64
        uint32_t queue_id;      /* Queue ID assigned by the hardware */
        uint32_t assoc_qid;     /* Queue ID associated with, for CQ/WQ/MQ */
        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 *,
 int lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
                        struct lpfc_queue **drqp, struct lpfc_queue **cqp,
                        uint32_t subtype);
-void lpfc_rq_adjust_repost(struct lpfc_hba *, struct lpfc_queue *, int);
 int lpfc_eq_destroy(struct lpfc_hba *, struct lpfc_queue *);
 int lpfc_cq_destroy(struct lpfc_hba *, struct lpfc_queue *);
 int lpfc_mq_destroy(struct lpfc_hba *, struct lpfc_queue *);