Commit 61f3d4bf authored by James Smart's avatar James Smart Committed by Martin K. Petersen

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: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 547077a4
...@@ -60,9 +60,9 @@ ...@@ -60,9 +60,9 @@
#define LPFC_MIN_DEVLOSS_TMO 1 #define LPFC_MIN_DEVLOSS_TMO 1
#define LPFC_MAX_DEVLOSS_TMO 255 #define LPFC_MAX_DEVLOSS_TMO 255
#define LPFC_DEF_MRQ_POST 256 #define LPFC_DEF_MRQ_POST 512
#define LPFC_MIN_MRQ_POST 32 #define LPFC_MIN_MRQ_POST 512
#define LPFC_MAX_MRQ_POST 512 #define LPFC_MAX_MRQ_POST 2048
/* /*
* Write key size should be multiple of 4. If write key is changed * Write key size should be multiple of 4. If write key is changed
......
...@@ -3390,6 +3390,11 @@ lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba) ...@@ -3390,6 +3390,11 @@ lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba)
*/ */
els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba); els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
nvmet_xri_cnt = phba->cfg_nvmet_mrq * phba->cfg_nvmet_mrq_post; 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; tot_cnt = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
if (nvmet_xri_cnt > tot_cnt) { if (nvmet_xri_cnt > tot_cnt) {
phba->cfg_nvmet_mrq_post = tot_cnt / phba->cfg_nvmet_mrq; phba->cfg_nvmet_mrq_post = tot_cnt / phba->cfg_nvmet_mrq;
...@@ -8158,7 +8163,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8158,7 +8163,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
/* Create NVMET Receive Queue for header */ /* Create NVMET Receive Queue for header */
qdesc = lpfc_sli4_queue_alloc(phba, qdesc = lpfc_sli4_queue_alloc(phba,
phba->sli4_hba.rq_esize, phba->sli4_hba.rq_esize,
phba->sli4_hba.rq_ecount); LPFC_NVMET_RQE_DEF_COUNT);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3146 Failed allocate " "3146 Failed allocate "
...@@ -8180,7 +8185,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8180,7 +8185,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
/* Create NVMET Receive Queue for data */ /* Create NVMET Receive Queue for data */
qdesc = lpfc_sli4_queue_alloc(phba, qdesc = lpfc_sli4_queue_alloc(phba,
phba->sli4_hba.rq_esize, phba->sli4_hba.rq_esize,
phba->sli4_hba.rq_ecount); LPFC_NVMET_RQE_DEF_COUNT);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3156 Failed allocate " "3156 Failed allocate "
...@@ -8770,9 +8775,6 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) ...@@ -8770,9 +8775,6 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
goto out_destroy; 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, rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
phba->sli4_hba.els_cq, LPFC_USOL); phba->sli4_hba.els_cq, LPFC_USOL);
if (rc) { if (rc) {
...@@ -11096,7 +11098,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -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_hba *phba;
struct lpfc_vport *vport = NULL; struct lpfc_vport *vport = NULL;
struct Scsi_Host *shost = NULL; struct Scsi_Host *shost = NULL;
int error, cnt; int error, cnt, num;
uint32_t cfg_mode, intr_mode; uint32_t cfg_mode, intr_mode;
/* Allocate memory for HBA structure */ /* 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,8 +11133,13 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
} }
cnt = phba->cfg_iocb_cnt * 1024; cnt = phba->cfg_iocb_cnt * 1024;
if (phba->nvmet_support) if (phba->nvmet_support) {
cnt += phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq; /* 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 */ /* Initialize and populate the iocb list per host */
lpfc_printf_log(phba, KERN_INFO, LOG_INIT, lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
......
...@@ -614,9 +614,9 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, ...@@ -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", lpfc_nvmeio_data(phba, "NVMET FCP CMND: xri x%x op x%x len x%x\n",
ctxp->oxid, rsp->op, rsp->rsplen); ctxp->oxid, rsp->op, rsp->rsplen);
ctxp->flag |= LPFC_NVMET_IO_INP;
rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq); rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq);
if (rc == WQE_SUCCESS) { if (rc == WQE_SUCCESS) {
ctxp->flag |= LPFC_NVMET_IO_INP;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
if (!phba->ktime_on) if (!phba->ktime_on)
return 0; return 0;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
********************************************************************/ ********************************************************************/
#define LPFC_NVMET_DEFAULT_SEGS (64 + 1) /* 256K IOs */ #define LPFC_NVMET_DEFAULT_SEGS (64 + 1) /* 256K IOs */
#define LPFC_NVMET_RQE_DEF_COUNT 512
#define LPFC_NVMET_SUCCESS_LEN 12 #define LPFC_NVMET_SUCCESS_LEN 12
/* Used for NVME Target */ /* Used for NVME Target */
......
...@@ -479,22 +479,23 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, ...@@ -479,22 +479,23 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
if (unlikely(!hq) || unlikely(!dq)) if (unlikely(!hq) || unlikely(!dq))
return -ENOMEM; return -ENOMEM;
put_index = hq->host_index; 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; temp_drqe = dq->qe[dq->host_index].rqe;
if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ) if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ)
return -EINVAL; return -EINVAL;
if (hq->host_index != dq->host_index) if (put_index != dq->host_index)
return -EINVAL; return -EINVAL;
/* If the host has not yet processed the next entry then we are done */ /* 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; return -EBUSY;
lpfc_sli_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size); lpfc_sli_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size);
lpfc_sli_pcimem_bcopy(drqe, temp_drqe, dq->entry_size); lpfc_sli_pcimem_bcopy(drqe, temp_drqe, dq->entry_size);
/* Update the host index to point to the next slot */ /* 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); dq->host_index = ((dq->host_index + 1) % dq->entry_count);
hq->RQ_buf_posted++;
/* Ring The Header Receive Queue Doorbell */ /* Ring The Header Receive Queue Doorbell */
if (!(hq->host_index % hq->entry_repost)) { if (!(hq->host_index % hq->entry_repost)) {
...@@ -512,7 +513,6 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, ...@@ -512,7 +513,6 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
} else { } else {
return -EINVAL; return -EINVAL;
} }
hq->RQ_buf_posted += hq->entry_repost;
writel(doorbell.word0, hq->db_regaddr); writel(doorbell.word0, hq->db_regaddr);
} }
return put_index; return put_index;
...@@ -6905,14 +6905,9 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) ...@@ -6905,14 +6905,9 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
INIT_LIST_HEAD(&rqbp->rqb_buffer_list); INIT_LIST_HEAD(&rqbp->rqb_buffer_list);
rqbp->rqb_alloc_buffer = lpfc_sli4_nvmet_alloc; rqbp->rqb_alloc_buffer = lpfc_sli4_nvmet_alloc;
rqbp->rqb_free_buffer = lpfc_sli4_nvmet_free; rqbp->rqb_free_buffer = lpfc_sli4_nvmet_free;
rqbp->entry_count = 256; rqbp->entry_count = LPFC_NVMET_RQE_DEF_COUNT;
rqbp->buffer_count = 0; 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( lpfc_post_rq_buffer(
phba, phba->sli4_hba.nvmet_mrq_hdr[i], phba, phba->sli4_hba.nvmet_mrq_hdr[i],
phba->sli4_hba.nvmet_mrq_data[i], phba->sli4_hba.nvmet_mrq_data[i],
...@@ -14892,34 +14887,6 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, ...@@ -14892,34 +14887,6 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
return status; 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 * lpfc_rq_create - Create a Receive Queue on the HBA
* @phba: HBA structure that indicates port to create a queue on. * @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, ...@@ -15105,6 +15072,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
hrq->subtype = subtype; hrq->subtype = subtype;
hrq->host_index = 0; hrq->host_index = 0;
hrq->hba_index = 0; hrq->hba_index = 0;
hrq->entry_repost = LPFC_RQ_REPOST;
/* now create the data queue */ /* now create the data queue */
lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE, 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,6 +15154,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
drq->subtype = subtype; drq->subtype = subtype;
drq->host_index = 0; drq->host_index = 0;
drq->hba_index = 0; drq->hba_index = 0;
drq->entry_repost = LPFC_RQ_REPOST;
/* link the header and data RQs onto the parent cq child list */ /* link the header and data RQs onto the parent cq child list */
list_add_tail(&hrq->list, &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, ...@@ -15343,6 +15312,7 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
hrq->subtype = subtype; hrq->subtype = subtype;
hrq->host_index = 0; hrq->host_index = 0;
hrq->hba_index = 0; hrq->hba_index = 0;
hrq->entry_repost = LPFC_RQ_REPOST;
drq->db_format = LPFC_DB_RING_FORMAT; drq->db_format = LPFC_DB_RING_FORMAT;
drq->db_regaddr = phba->sli4_hba.RQDBregaddr; drq->db_regaddr = phba->sli4_hba.RQDBregaddr;
...@@ -15351,6 +15321,7 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp, ...@@ -15351,6 +15321,7 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
drq->subtype = subtype; drq->subtype = subtype;
drq->host_index = 0; drq->host_index = 0;
drq->hba_index = 0; drq->hba_index = 0;
drq->entry_repost = LPFC_RQ_REPOST;
list_add_tail(&hrq->list, &cq->child_list); list_add_tail(&hrq->list, &cq->child_list);
list_add_tail(&drq->list, &cq->child_list); list_add_tail(&drq->list, &cq->child_list);
......
...@@ -156,6 +156,7 @@ struct lpfc_queue { ...@@ -156,6 +156,7 @@ struct lpfc_queue {
uint32_t entry_size; /* Size of each queue entry. */ uint32_t entry_size; /* Size of each queue entry. */
uint32_t entry_repost; /* Count of entries before doorbell is rung */ uint32_t entry_repost; /* Count of entries before doorbell is rung */
#define LPFC_QUEUE_MIN_REPOST 8 #define LPFC_QUEUE_MIN_REPOST 8
#define LPFC_RQ_REPOST 64
uint32_t queue_id; /* Queue ID assigned by the hardware */ uint32_t queue_id; /* Queue ID assigned by the hardware */
uint32_t assoc_qid; /* Queue ID associated with, for CQ/WQ/MQ */ uint32_t assoc_qid; /* Queue ID associated with, for CQ/WQ/MQ */
uint32_t page_count; /* Number of pages allocated for this queue */ 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 *, ...@@ -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, int lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
struct lpfc_queue **drqp, struct lpfc_queue **cqp, struct lpfc_queue **drqp, struct lpfc_queue **cqp,
uint32_t subtype); 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_eq_destroy(struct lpfc_hba *, struct lpfc_queue *);
int lpfc_cq_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 *); int lpfc_mq_destroy(struct lpfc_hba *, struct lpfc_queue *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment