Commit 81b96eda authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Expand WQE capability of every NVME hardware queue

Hardware queues are a fast staging area to push commands into the
adapter.  The adapter should drain them extremely quickly. However,
under heavy io load, the host cpu is pushing commands faster than the
drain rate of the adapter causing the driver to resource busy commands.

Enlarge the hardware queue (wq & cq) to support a larger number of queue
entries (4x the prior size) before backpressure. Enlarging the queue
requires larger contiguous buffers (16k) per logical page for the
hardware. This changed calling sequences that were expecting 4K page
sizes that now must pass a parameter with the page sizes. It also
required use of a new version of an adapter command that can vary the
page size values.
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.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c73455e1
...@@ -1122,6 +1122,7 @@ struct cq_context { ...@@ -1122,6 +1122,7 @@ struct cq_context {
#define LPFC_CQ_CNT_256 0x0 #define LPFC_CQ_CNT_256 0x0
#define LPFC_CQ_CNT_512 0x1 #define LPFC_CQ_CNT_512 0x1
#define LPFC_CQ_CNT_1024 0x2 #define LPFC_CQ_CNT_1024 0x2
#define LPFC_CQ_CNT_WORD7 0x3
uint32_t word1; uint32_t word1;
#define lpfc_cq_eq_id_SHIFT 22 /* Version 0 Only */ #define lpfc_cq_eq_id_SHIFT 22 /* Version 0 Only */
#define lpfc_cq_eq_id_MASK 0x000000FF #define lpfc_cq_eq_id_MASK 0x000000FF
...@@ -1129,7 +1130,7 @@ struct cq_context { ...@@ -1129,7 +1130,7 @@ struct cq_context {
#define lpfc_cq_eq_id_2_SHIFT 0 /* Version 2 Only */ #define lpfc_cq_eq_id_2_SHIFT 0 /* Version 2 Only */
#define lpfc_cq_eq_id_2_MASK 0x0000FFFF #define lpfc_cq_eq_id_2_MASK 0x0000FFFF
#define lpfc_cq_eq_id_2_WORD word1 #define lpfc_cq_eq_id_2_WORD word1
uint32_t reserved0; uint32_t lpfc_cq_context_count; /* Version 2 Only */
uint32_t reserved1; uint32_t reserved1;
}; };
...@@ -1193,6 +1194,9 @@ struct lpfc_mbx_cq_create_set { ...@@ -1193,6 +1194,9 @@ struct lpfc_mbx_cq_create_set {
#define lpfc_mbx_cq_create_set_arm_SHIFT 31 #define lpfc_mbx_cq_create_set_arm_SHIFT 31
#define lpfc_mbx_cq_create_set_arm_MASK 0x00000001 #define lpfc_mbx_cq_create_set_arm_MASK 0x00000001
#define lpfc_mbx_cq_create_set_arm_WORD word2 #define lpfc_mbx_cq_create_set_arm_WORD word2
#define lpfc_mbx_cq_create_set_cq_cnt_SHIFT 16
#define lpfc_mbx_cq_create_set_cq_cnt_MASK 0x00007FFF
#define lpfc_mbx_cq_create_set_cq_cnt_WORD word2
#define lpfc_mbx_cq_create_set_num_cq_SHIFT 0 #define lpfc_mbx_cq_create_set_num_cq_SHIFT 0
#define lpfc_mbx_cq_create_set_num_cq_MASK 0x0000FFFF #define lpfc_mbx_cq_create_set_num_cq_MASK 0x0000FFFF
#define lpfc_mbx_cq_create_set_num_cq_WORD word2 #define lpfc_mbx_cq_create_set_num_cq_WORD word2
......
...@@ -7958,10 +7958,10 @@ static int ...@@ -7958,10 +7958,10 @@ static int
lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx)
{ {
struct lpfc_queue *qdesc; struct lpfc_queue *qdesc;
int cnt;
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_NVME_PAGE_SIZE,
phba->sli4_hba.cq_ecount); phba->sli4_hba.cq_esize,
LPFC_NVME_CQSIZE);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0508 Failed allocate fast-path NVME CQ (%d)\n", "0508 Failed allocate fast-path NVME CQ (%d)\n",
...@@ -7970,8 +7970,8 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) ...@@ -7970,8 +7970,8 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx)
} }
phba->sli4_hba.nvme_cq[wqidx] = qdesc; phba->sli4_hba.nvme_cq[wqidx] = qdesc;
cnt = LPFC_NVME_WQSIZE; qdesc = lpfc_sli4_queue_alloc(phba, LPFC_NVME_PAGE_SIZE,
qdesc = lpfc_sli4_queue_alloc(phba, LPFC_WQE128_SIZE, cnt); LPFC_WQE128_SIZE, LPFC_NVME_WQSIZE);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0509 Failed allocate fast-path NVME WQ (%d)\n", "0509 Failed allocate fast-path NVME WQ (%d)\n",
...@@ -7990,8 +7990,9 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) ...@@ -7990,8 +7990,9 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
uint32_t wqesize; uint32_t wqesize;
/* Create Fast Path FCP CQs */ /* Create Fast Path FCP CQs */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.cq_ecount); phba->sli4_hba.cq_esize,
phba->sli4_hba.cq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx); "0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx);
...@@ -8002,7 +8003,8 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) ...@@ -8002,7 +8003,8 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx)
/* Create Fast Path FCP WQs */ /* Create Fast Path FCP WQs */
wqesize = (phba->fcp_embed_io) ? wqesize = (phba->fcp_embed_io) ?
LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
qdesc = lpfc_sli4_queue_alloc(phba, wqesize, phba->sli4_hba.wq_ecount); qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
wqesize, phba->sli4_hba.wq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0503 Failed allocate fast-path FCP WQ (%d)\n", "0503 Failed allocate fast-path FCP WQ (%d)\n",
...@@ -8173,7 +8175,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8173,7 +8175,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
/* Create HBA Event Queues (EQs) */ /* Create HBA Event Queues (EQs) */
for (idx = 0; idx < io_channel; idx++) { for (idx = 0; idx < io_channel; idx++) {
/* Create EQs */ /* Create EQs */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.eq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.eq_esize,
phba->sli4_hba.eq_ecount); phba->sli4_hba.eq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8196,8 +8199,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8196,8 +8199,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
if (phba->nvmet_support) { if (phba->nvmet_support) {
for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) {
qdesc = lpfc_sli4_queue_alloc(phba, qdesc = lpfc_sli4_queue_alloc(phba,
phba->sli4_hba.cq_esize, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.cq_ecount); phba->sli4_hba.cq_esize,
phba->sli4_hba.cq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3142 Failed allocate NVME " "3142 Failed allocate NVME "
...@@ -8213,7 +8217,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8213,7 +8217,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
*/ */
/* Create slow-path Mailbox Command Complete Queue */ /* Create slow-path Mailbox Command Complete Queue */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.cq_esize,
phba->sli4_hba.cq_ecount); phba->sli4_hba.cq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8223,7 +8228,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8223,7 +8228,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
phba->sli4_hba.mbx_cq = qdesc; phba->sli4_hba.mbx_cq = qdesc;
/* Create slow-path ELS Complete Queue */ /* Create slow-path ELS Complete Queue */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.cq_esize,
phba->sli4_hba.cq_ecount); phba->sli4_hba.cq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8239,7 +8245,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8239,7 +8245,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
/* Create Mailbox Command Queue */ /* Create Mailbox Command Queue */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.mq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.mq_esize,
phba->sli4_hba.mq_ecount); phba->sli4_hba.mq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8253,7 +8260,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8253,7 +8260,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
*/ */
/* Create slow-path ELS Work Queue */ /* Create slow-path ELS Work Queue */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.wq_esize,
phba->sli4_hba.wq_ecount); phba->sli4_hba.wq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8265,7 +8273,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8265,7 +8273,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
/* Create NVME LS Complete Queue */ /* Create NVME LS Complete Queue */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.cq_esize,
phba->sli4_hba.cq_ecount); phba->sli4_hba.cq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8275,7 +8284,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8275,7 +8284,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
phba->sli4_hba.nvmels_cq = qdesc; phba->sli4_hba.nvmels_cq = qdesc;
/* Create NVME LS Work Queue */ /* Create NVME LS Work Queue */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.wq_esize,
phba->sli4_hba.wq_ecount); phba->sli4_hba.wq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8291,7 +8301,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8291,7 +8301,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
*/ */
/* Create Receive Queue for header */ /* Create Receive Queue for header */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.rq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.rq_esize,
phba->sli4_hba.rq_ecount); phba->sli4_hba.rq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8301,7 +8312,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8301,7 +8312,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
phba->sli4_hba.hdr_rq = qdesc; phba->sli4_hba.hdr_rq = qdesc;
/* Create Receive Queue for data */ /* Create Receive Queue for data */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.rq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.rq_esize,
phba->sli4_hba.rq_ecount); phba->sli4_hba.rq_ecount);
if (!qdesc) { if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
...@@ -8314,6 +8326,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8314,6 +8326,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) {
/* Create NVMET Receive Queue for header */ /* Create NVMET Receive Queue for header */
qdesc = lpfc_sli4_queue_alloc(phba, qdesc = lpfc_sli4_queue_alloc(phba,
LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.rq_esize, phba->sli4_hba.rq_esize,
LPFC_NVMET_RQE_DEF_COUNT); LPFC_NVMET_RQE_DEF_COUNT);
if (!qdesc) { if (!qdesc) {
...@@ -8339,6 +8352,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) ...@@ -8339,6 +8352,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,
LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.rq_esize, phba->sli4_hba.rq_esize,
LPFC_NVMET_RQE_DEF_COUNT); LPFC_NVMET_RQE_DEF_COUNT);
if (!qdesc) { if (!qdesc) {
...@@ -8514,6 +8528,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq, ...@@ -8514,6 +8528,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq,
qidx, (uint32_t)rc); qidx, (uint32_t)rc);
return rc; return rc;
} }
cq->chann = qidx;
if (qtype != LPFC_MBOX) { if (qtype != LPFC_MBOX) {
/* Setup nvme_cq_map for fast lookup */ /* Setup nvme_cq_map for fast lookup */
...@@ -8533,6 +8548,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq, ...@@ -8533,6 +8548,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq,
/* no need to tear down cq - caller will do so */ /* no need to tear down cq - caller will do so */
return rc; return rc;
} }
wq->chann = qidx;
/* Bind this CQ/WQ to the NVME ring */ /* Bind this CQ/WQ to the NVME ring */
pring = wq->pring; pring = wq->pring;
...@@ -8773,6 +8789,8 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) ...@@ -8773,6 +8789,8 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
"rc = 0x%x\n", (uint32_t)rc); "rc = 0x%x\n", (uint32_t)rc);
goto out_destroy; goto out_destroy;
} }
phba->sli4_hba.nvmet_cqset[0]->chann = 0;
lpfc_printf_log(phba, KERN_INFO, LOG_INIT, lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"6090 NVMET CQ setup: cq-id=%d, " "6090 NVMET CQ setup: cq-id=%d, "
"parent eq-id=%d\n", "parent eq-id=%d\n",
...@@ -12141,7 +12159,8 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) ...@@ -12141,7 +12159,8 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
uint32_t wqesize; uint32_t wqesize;
/* Create FOF EQ */ /* Create FOF EQ */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.eq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.eq_esize,
phba->sli4_hba.eq_ecount); phba->sli4_hba.eq_ecount);
if (!qdesc) if (!qdesc)
goto out_error; goto out_error;
...@@ -12151,8 +12170,9 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) ...@@ -12151,8 +12170,9 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
if (phba->cfg_fof) { if (phba->cfg_fof) {
/* Create OAS CQ */ /* Create OAS CQ */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
phba->sli4_hba.cq_ecount); phba->sli4_hba.cq_esize,
phba->sli4_hba.cq_ecount);
if (!qdesc) if (!qdesc)
goto out_error; goto out_error;
...@@ -12161,7 +12181,8 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) ...@@ -12161,7 +12181,8 @@ lpfc_fof_queue_create(struct lpfc_hba *phba)
/* Create OAS WQ */ /* Create OAS WQ */
wqesize = (phba->fcp_embed_io) ? wqesize = (phba->fcp_embed_io) ?
LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize;
qdesc = lpfc_sli4_queue_alloc(phba, wqesize, qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE,
wqesize,
phba->sli4_hba.wq_ecount); phba->sli4_hba.wq_ecount);
if (!qdesc) if (!qdesc)
......
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
********************************************************************/ ********************************************************************/
#define LPFC_NVME_DEFAULT_SEGS (64 + 1) /* 256K IOs */ #define LPFC_NVME_DEFAULT_SEGS (64 + 1) /* 256K IOs */
#define LPFC_NVME_WQSIZE 256 #define LPFC_NVME_WQSIZE 1024
#define LPFC_NVME_CQSIZE 4096
#define LPFC_NVME_ERSP_LEN 0x20 #define LPFC_NVME_ERSP_LEN 0x20
......
...@@ -13919,7 +13919,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) ...@@ -13919,7 +13919,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue)
while (!list_empty(&queue->page_list)) { while (!list_empty(&queue->page_list)) {
list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf, list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf,
list); list);
dma_free_coherent(&queue->phba->pcidev->dev, SLI4_PAGE_SIZE, dma_free_coherent(&queue->phba->pcidev->dev, queue->page_size,
dmabuf->virt, dmabuf->phys); dmabuf->virt, dmabuf->phys);
kfree(dmabuf); kfree(dmabuf);
} }
...@@ -13938,6 +13938,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) ...@@ -13938,6 +13938,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue)
/** /**
* lpfc_sli4_queue_alloc - Allocate and initialize a queue structure * lpfc_sli4_queue_alloc - Allocate and initialize a queue structure
* @phba: The HBA that this queue is being created on. * @phba: The HBA that this queue is being created on.
* @page_size: The size of a queue page
* @entry_size: The size of each queue entry for this queue. * @entry_size: The size of each queue entry for this queue.
* @entry count: The number of entries that this queue will handle. * @entry count: The number of entries that this queue will handle.
* *
...@@ -13946,8 +13947,8 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) ...@@ -13946,8 +13947,8 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue)
* queue on the HBA. * queue on the HBA.
**/ **/
struct lpfc_queue * struct lpfc_queue *
lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size, lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size,
uint32_t entry_count) uint32_t entry_size, uint32_t entry_count)
{ {
struct lpfc_queue *queue; struct lpfc_queue *queue;
struct lpfc_dmabuf *dmabuf; struct lpfc_dmabuf *dmabuf;
...@@ -13956,7 +13957,7 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size, ...@@ -13956,7 +13957,7 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size,
uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
if (!phba->sli4_hba.pc_sli4_params.supported) if (!phba->sli4_hba.pc_sli4_params.supported)
hw_page_size = SLI4_PAGE_SIZE; hw_page_size = page_size;
queue = kzalloc(sizeof(struct lpfc_queue) + queue = kzalloc(sizeof(struct lpfc_queue) +
(sizeof(union sli4_qe) * entry_count), GFP_KERNEL); (sizeof(union sli4_qe) * entry_count), GFP_KERNEL);
...@@ -13973,6 +13974,15 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size, ...@@ -13973,6 +13974,15 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size,
INIT_LIST_HEAD(&queue->wq_list); INIT_LIST_HEAD(&queue->wq_list);
INIT_LIST_HEAD(&queue->page_list); INIT_LIST_HEAD(&queue->page_list);
INIT_LIST_HEAD(&queue->child_list); INIT_LIST_HEAD(&queue->child_list);
/* Set queue parameters now. If the system cannot provide memory
* resources, the free routine needs to know what was allocated.
*/
queue->entry_size = entry_size;
queue->entry_count = entry_count;
queue->page_size = hw_page_size;
queue->phba = phba;
for (x = 0, total_qe_count = 0; x < queue->page_count; x++) { for (x = 0, total_qe_count = 0; x < queue->page_count; x++) {
dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
if (!dmabuf) if (!dmabuf)
...@@ -13994,9 +14004,6 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size, ...@@ -13994,9 +14004,6 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size,
queue->qe[total_qe_count].address = dma_pointer; queue->qe[total_qe_count].address = dma_pointer;
} }
} }
queue->entry_size = entry_size;
queue->entry_count = entry_count;
queue->phba = phba;
INIT_WORK(&queue->irqwork, lpfc_sli4_hba_process_cq); INIT_WORK(&queue->irqwork, lpfc_sli4_hba_process_cq);
INIT_WORK(&queue->spwork, lpfc_sli4_sp_process_cq); INIT_WORK(&queue->spwork, lpfc_sli4_sp_process_cq);
...@@ -14299,7 +14306,7 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, ...@@ -14299,7 +14306,7 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
if (!cq || !eq) if (!cq || !eq)
return -ENODEV; return -ENODEV;
if (!phba->sli4_hba.pc_sli4_params.supported) if (!phba->sli4_hba.pc_sli4_params.supported)
hw_page_size = SLI4_PAGE_SIZE; hw_page_size = cq->page_size;
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox) if (!mbox)
...@@ -14318,8 +14325,8 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, ...@@ -14318,8 +14325,8 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
bf_set(lpfc_mbox_hdr_version, &shdr->request, bf_set(lpfc_mbox_hdr_version, &shdr->request,
phba->sli4_hba.pc_sli4_params.cqv); phba->sli4_hba.pc_sli4_params.cqv);
if (phba->sli4_hba.pc_sli4_params.cqv == LPFC_Q_CREATE_VERSION_2) { if (phba->sli4_hba.pc_sli4_params.cqv == LPFC_Q_CREATE_VERSION_2) {
/* FW only supports 1. Should be PAGE_SIZE/SLI4_PAGE_SIZE */ bf_set(lpfc_mbx_cq_create_page_size, &cq_create->u.request,
bf_set(lpfc_mbx_cq_create_page_size, &cq_create->u.request, 1); (cq->page_size / SLI4_PAGE_SIZE));
bf_set(lpfc_cq_eq_id_2, &cq_create->u.request.context, bf_set(lpfc_cq_eq_id_2, &cq_create->u.request.context,
eq->queue_id); eq->queue_id);
} else { } else {
...@@ -14327,6 +14334,18 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, ...@@ -14327,6 +14334,18 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
eq->queue_id); eq->queue_id);
} }
switch (cq->entry_count) { switch (cq->entry_count) {
case 2048:
case 4096:
if (phba->sli4_hba.pc_sli4_params.cqv ==
LPFC_Q_CREATE_VERSION_2) {
cq_create->u.request.context.lpfc_cq_context_count =
cq->entry_count;
bf_set(lpfc_cq_context_count,
&cq_create->u.request.context,
LPFC_CQ_CNT_WORD7);
break;
}
/* Fall Thru */
default: default:
lpfc_printf_log(phba, KERN_ERR, LOG_SLI, lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0361 Unsupported CQ count: " "0361 Unsupported CQ count: "
...@@ -14352,7 +14371,7 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, ...@@ -14352,7 +14371,7 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
break; break;
} }
list_for_each_entry(dmabuf, &cq->page_list, list) { list_for_each_entry(dmabuf, &cq->page_list, list) {
memset(dmabuf->virt, 0, hw_page_size); memset(dmabuf->virt, 0, cq->page_size);
cq_create->u.request.page[dmabuf->buffer_tag].addr_lo = cq_create->u.request.page[dmabuf->buffer_tag].addr_lo =
putPaddrLow(dmabuf->phys); putPaddrLow(dmabuf->phys);
cq_create->u.request.page[dmabuf->buffer_tag].addr_hi = cq_create->u.request.page[dmabuf->buffer_tag].addr_hi =
...@@ -14433,8 +14452,6 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp, ...@@ -14433,8 +14452,6 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
numcq = phba->cfg_nvmet_mrq; numcq = phba->cfg_nvmet_mrq;
if (!cqp || !eqp || !numcq) if (!cqp || !eqp || !numcq)
return -ENODEV; return -ENODEV;
if (!phba->sli4_hba.pc_sli4_params.supported)
hw_page_size = SLI4_PAGE_SIZE;
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox) if (!mbox)
...@@ -14465,6 +14482,8 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp, ...@@ -14465,6 +14482,8 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
status = -ENOMEM; status = -ENOMEM;
goto out; goto out;
} }
if (!phba->sli4_hba.pc_sli4_params.supported)
hw_page_size = cq->page_size;
switch (idx) { switch (idx) {
case 0: case 0:
...@@ -14482,6 +14501,19 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp, ...@@ -14482,6 +14501,19 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
bf_set(lpfc_mbx_cq_create_set_num_cq, bf_set(lpfc_mbx_cq_create_set_num_cq,
&cq_set->u.request, numcq); &cq_set->u.request, numcq);
switch (cq->entry_count) { switch (cq->entry_count) {
case 2048:
case 4096:
if (phba->sli4_hba.pc_sli4_params.cqv ==
LPFC_Q_CREATE_VERSION_2) {
bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
&cq_set->u.request,
cq->entry_count);
bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
&cq_set->u.request,
LPFC_CQ_CNT_WORD7);
break;
}
/* Fall Thru */
default: default:
lpfc_printf_log(phba, KERN_ERR, LOG_SLI, lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"3118 Bad CQ count. (%d)\n", "3118 Bad CQ count. (%d)\n",
...@@ -14578,6 +14610,7 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp, ...@@ -14578,6 +14610,7 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
cq->host_index = 0; cq->host_index = 0;
cq->hba_index = 0; cq->hba_index = 0;
cq->entry_repost = LPFC_CQ_REPOST; cq->entry_repost = LPFC_CQ_REPOST;
cq->chann = idx;
rc = 0; rc = 0;
list_for_each_entry(dmabuf, &cq->page_list, list) { list_for_each_entry(dmabuf, &cq->page_list, list) {
...@@ -14872,12 +14905,13 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, ...@@ -14872,12 +14905,13 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
void __iomem *bar_memmap_p; void __iomem *bar_memmap_p;
uint32_t db_offset; uint32_t db_offset;
uint16_t pci_barset; uint16_t pci_barset;
uint8_t wq_create_version;
/* sanity check on queue memory */ /* sanity check on queue memory */
if (!wq || !cq) if (!wq || !cq)
return -ENODEV; return -ENODEV;
if (!phba->sli4_hba.pc_sli4_params.supported) if (!phba->sli4_hba.pc_sli4_params.supported)
hw_page_size = SLI4_PAGE_SIZE; hw_page_size = wq->page_size;
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox) if (!mbox)
...@@ -14898,7 +14932,12 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, ...@@ -14898,7 +14932,12 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
bf_set(lpfc_mbox_hdr_version, &shdr->request, bf_set(lpfc_mbox_hdr_version, &shdr->request,
phba->sli4_hba.pc_sli4_params.wqv); phba->sli4_hba.pc_sli4_params.wqv);
switch (phba->sli4_hba.pc_sli4_params.wqv) { if (phba->sli4_hba.pc_sli4_params.wqsize & LPFC_WQ_SZ128_SUPPORT)
wq_create_version = LPFC_Q_CREATE_VERSION_1;
else
wq_create_version = LPFC_Q_CREATE_VERSION_0;
switch (wq_create_version) {
case LPFC_Q_CREATE_VERSION_0: case LPFC_Q_CREATE_VERSION_0:
switch (wq->entry_size) { switch (wq->entry_size) {
default: default:
...@@ -14956,7 +14995,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, ...@@ -14956,7 +14995,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
} }
bf_set(lpfc_mbx_wq_create_page_size, bf_set(lpfc_mbx_wq_create_page_size,
&wq_create->u.request_1, &wq_create->u.request_1,
LPFC_WQ_PAGE_SIZE_4096); (wq->page_size / SLI4_PAGE_SIZE));
page = wq_create->u.request_1.page; page = wq_create->u.request_1.page;
break; break;
default: default:
......
...@@ -161,7 +161,6 @@ struct lpfc_queue { ...@@ -161,7 +161,6 @@ struct lpfc_queue {
#define LPFC_RELEASE_NOTIFICATION_INTERVAL 32 /* For WQs */ #define LPFC_RELEASE_NOTIFICATION_INTERVAL 32 /* For WQs */
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 host_index; /* The host's index for putting or getting */ uint32_t host_index; /* The host's index for putting or getting */
uint32_t hba_index; /* The last known hba index for get or put */ uint32_t hba_index; /* The last known hba index for get or put */
...@@ -169,6 +168,11 @@ struct lpfc_queue { ...@@ -169,6 +168,11 @@ struct lpfc_queue {
struct lpfc_rqb *rqbp; /* ptr to RQ buffers */ struct lpfc_rqb *rqbp; /* ptr to RQ buffers */
uint32_t q_mode; uint32_t q_mode;
uint16_t page_count; /* Number of pages allocated for this queue */
uint16_t page_size; /* size of page allocated for this queue */
#define LPFC_NVME_PAGE_SIZE 16384
#define LPFC_DEFAULT_PAGE_SIZE 4096
uint16_t chann; /* IO channel this queue is associated with */
uint16_t db_format; uint16_t db_format;
#define LPFC_DB_RING_FORMAT 0x01 #define LPFC_DB_RING_FORMAT 0x01
#define LPFC_DB_LIST_FORMAT 0x02 #define LPFC_DB_LIST_FORMAT 0x02
...@@ -769,7 +773,7 @@ int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *, ...@@ -769,7 +773,7 @@ int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *,
void lpfc_sli4_hba_reset(struct lpfc_hba *); void lpfc_sli4_hba_reset(struct lpfc_hba *);
struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t,
uint32_t); uint32_t, uint32_t);
void lpfc_sli4_queue_free(struct lpfc_queue *); void lpfc_sli4_queue_free(struct lpfc_queue *);
int lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint32_t); int lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint32_t);
int lpfc_modify_hba_eq_delay(struct lpfc_hba *phba, uint32_t startq, int lpfc_modify_hba_eq_delay(struct lpfc_hba *phba, uint32_t startq,
......
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