From patchwork Fri Nov 10 01:08:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 10052213 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E2E2E6032D for ; Fri, 10 Nov 2017 01:08:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D4B8E2B20E for ; Fri, 10 Nov 2017 01:08:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C95F32B227; Fri, 10 Nov 2017 01:08:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C0712B20E for ; Fri, 10 Nov 2017 01:08:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755506AbdKJBIs (ORCPT ); Thu, 9 Nov 2017 20:08:48 -0500 Received: from mail-qk0-f193.google.com ([209.85.220.193]:48533 "EHLO mail-qk0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755255AbdKJBIp (ORCPT ); Thu, 9 Nov 2017 20:08:45 -0500 Received: by mail-qk0-f193.google.com with SMTP id a142so10115664qkb.5 for ; Thu, 09 Nov 2017 17:08:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=trUODO8rb/zgmHhrdQT8BbY9+k9G98W7CQq5KQidfP0=; b=Of4UjQP7Ia4fQYJST1dlEXHLPlcnjatWpileEX+TYgGZ7PGdVxvS4AZIyjoO6XasJ/ f6mU6+j/010Aovu2brdHGv7SzSlRUWOuApkxZf2vBmPQ3qHFcrnMz8MZRoj2jd1QLlw7 OGAMC+TIhK9HLtmu6bSYo2TQePT7cSK/2uayk5doP5xHhVrikAIKr6Awiz4ThrUH/H4h FO0lVA+fcZcC1MjYcOOslIKkSOz5/+vQRWqUmDvnppUTgMP5xK/upO3VPk2HzQ7C5Lzi D8TUTt0AyU2tNxeoyQo9gOY251LApx1XZZGMpvG7dcBSdjQWPN5a+aB5CR3p5SamcjoW oOhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=trUODO8rb/zgmHhrdQT8BbY9+k9G98W7CQq5KQidfP0=; b=tlfVZljMcM1yIlCoZqLkLWTGQ9r1SiAT1/rvaEimI6Mcxm1AMPGJpZIE9xkdy2VIM5 y9buzypil6vr7HPmZoWDwe3beycdpW5Yj8Xd13qtG0dg7Pni8uEs9aWAMhgzFzuWy6qz zpelhMxSX4+HhM9GSym6UtlqPhns/kMCR0MZecUdjTw6hKpG0og9qGpIlvP6ecG2xfxP PdC9Yt0GrLRx0mgcDLGywDrmswLmC1T3JHbTDxvbFdK3fmrKYQx8JPF/3FYSJMTs2kOf iYpxT3RB/PrJPRZYSvQxbRhrtgcxtG18J+jfz6dlLUAJcx122E8fvOlj2yupVPW6mYus jzGg== X-Gm-Message-State: AJaThX5UB50lbnE6mZchL/LRAA5EtqIggF3zB7sEk7wLAyv/XySRq9Ol cqv5POgk6F/HWaMbACIW2I7VsKa7 X-Google-Smtp-Source: AGs4zMbroNumT+Q9Le1zrNYQnjzBZAkq9QBkEEvmTfzMwf2ffeGoOpZ75jLFJs8nOXy1pMSPz+5zqw== X-Received: by 10.55.167.139 with SMTP id q133mr3899951qke.328.1510276124607; Thu, 09 Nov 2017 17:08:44 -0800 (PST) Received: from pallmd1.broadcom.com ([192.19.255.250]) by smtp.gmail.com with ESMTPSA id j48sm5661969qta.96.2017.11.09.17.08.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 Nov 2017 17:08:44 -0800 (PST) From: James Smart To: linux-scsi@vger.kernel.org Cc: James Smart , Dick Kennedy , James Smart Subject: [PATCH v2 02/17] lpfc: Expand WQE capability of every NVME hardware queue Date: Thu, 9 Nov 2017 17:08:19 -0800 Message-Id: <20171110010834.4542-3-jsmart2021@gmail.com> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171110010834.4542-1-jsmart2021@gmail.com> References: <20171110010834.4542-1-jsmart2021@gmail.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinecke --- drivers/scsi/lpfc/lpfc_hw4.h | 6 +++- drivers/scsi/lpfc/lpfc_init.c | 67 ++++++++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_nvme.h | 3 +- drivers/scsi/lpfc/lpfc_sli.c | 71 +++++++++++++++++++++++++++++++++---------- drivers/scsi/lpfc/lpfc_sli4.h | 8 +++-- 5 files changed, 112 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 2b145966c73f..73c2f6971d2b 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1122,6 +1122,7 @@ struct cq_context { #define LPFC_CQ_CNT_256 0x0 #define LPFC_CQ_CNT_512 0x1 #define LPFC_CQ_CNT_1024 0x2 +#define LPFC_CQ_CNT_WORD7 0x3 uint32_t word1; #define lpfc_cq_eq_id_SHIFT 22 /* Version 0 Only */ #define lpfc_cq_eq_id_MASK 0x000000FF @@ -1129,7 +1130,7 @@ struct cq_context { #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_WORD word1 - uint32_t reserved0; + uint32_t lpfc_cq_context_count; /* Version 2 Only */ uint32_t reserved1; }; @@ -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_MASK 0x00000001 #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_MASK 0x0000FFFF #define lpfc_mbx_cq_create_set_num_cq_WORD word2 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 4ffdde5808ee..52c039e9f4a4 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7964,10 +7964,10 @@ static int lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) { struct lpfc_queue *qdesc; - int cnt; - qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, - phba->sli4_hba.cq_ecount); + qdesc = lpfc_sli4_queue_alloc(phba, LPFC_NVME_PAGE_SIZE, + phba->sli4_hba.cq_esize, + LPFC_NVME_CQSIZE); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0508 Failed allocate fast-path NVME CQ (%d)\n", @@ -7976,8 +7976,8 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) } phba->sli4_hba.nvme_cq[wqidx] = qdesc; - cnt = LPFC_NVME_WQSIZE; - qdesc = lpfc_sli4_queue_alloc(phba, LPFC_WQE128_SIZE, cnt); + qdesc = lpfc_sli4_queue_alloc(phba, LPFC_NVME_PAGE_SIZE, + LPFC_WQE128_SIZE, LPFC_NVME_WQSIZE); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0509 Failed allocate fast-path NVME WQ (%d)\n", @@ -7996,8 +7996,9 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) uint32_t wqesize; /* Create Fast Path FCP CQs */ - qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, - phba->sli4_hba.cq_ecount); + qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, + phba->sli4_hba.cq_esize, + phba->sli4_hba.cq_ecount); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx); @@ -8008,7 +8009,8 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) /* Create Fast Path FCP WQs */ wqesize = (phba->fcp_embed_io) ? 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) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0503 Failed allocate fast-path FCP WQ (%d)\n", @@ -8179,7 +8181,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) /* Create HBA Event Queues (EQs) */ for (idx = 0; idx < io_channel; idx++) { /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8202,8 +8205,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) if (phba->nvmet_support) { for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { qdesc = lpfc_sli4_queue_alloc(phba, - phba->sli4_hba.cq_esize, - phba->sli4_hba.cq_ecount); + LPFC_DEFAULT_PAGE_SIZE, + phba->sli4_hba.cq_esize, + phba->sli4_hba.cq_ecount); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3142 Failed allocate NVME " @@ -8219,7 +8223,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) */ /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8229,7 +8234,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) phba->sli4_hba.mbx_cq = qdesc; /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8245,7 +8251,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8259,7 +8266,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) */ /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8271,7 +8279,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8281,7 +8290,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) phba->sli4_hba.nvmels_cq = qdesc; /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8297,7 +8307,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) */ /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8307,7 +8318,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) phba->sli4_hba.hdr_rq = qdesc; /* 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); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -8320,6 +8332,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { /* Create NVMET Receive Queue for header */ qdesc = lpfc_sli4_queue_alloc(phba, + LPFC_DEFAULT_PAGE_SIZE, phba->sli4_hba.rq_esize, LPFC_NVMET_RQE_DEF_COUNT); if (!qdesc) { @@ -8345,6 +8358,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) /* Create NVMET Receive Queue for data */ qdesc = lpfc_sli4_queue_alloc(phba, + LPFC_DEFAULT_PAGE_SIZE, phba->sli4_hba.rq_esize, LPFC_NVMET_RQE_DEF_COUNT); if (!qdesc) { @@ -8520,6 +8534,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq, qidx, (uint32_t)rc); return rc; } + cq->chann = qidx; if (qtype != LPFC_MBOX) { /* Setup nvme_cq_map for fast lookup */ @@ -8539,6 +8554,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq, /* no need to tear down cq - caller will do so */ return rc; } + wq->chann = qidx; /* Bind this CQ/WQ to the NVME ring */ pring = wq->pring; @@ -8779,6 +8795,8 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) "rc = 0x%x\n", (uint32_t)rc); goto out_destroy; } + phba->sli4_hba.nvmet_cqset[0]->chann = 0; + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "6090 NVMET CQ setup: cq-id=%d, " "parent eq-id=%d\n", @@ -12147,7 +12165,8 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) uint32_t wqesize; /* 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); if (!qdesc) goto out_error; @@ -12157,8 +12176,9 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) if (phba->cfg_fof) { /* Create OAS CQ */ - qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.cq_esize, - phba->sli4_hba.cq_ecount); + qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, + phba->sli4_hba.cq_esize, + phba->sli4_hba.cq_ecount); if (!qdesc) goto out_error; @@ -12167,7 +12187,8 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) /* Create OAS WQ */ wqesize = (phba->fcp_embed_io) ? 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); if (!qdesc) diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index d192bb268f99..fbfc1786cd04 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h @@ -22,7 +22,8 @@ ********************************************************************/ #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 diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 98c488ab720b..2ad444ce7529 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -13919,7 +13919,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) while (!list_empty(&queue->page_list)) { list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf, 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); kfree(dmabuf); } @@ -13938,6 +13938,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) /** * lpfc_sli4_queue_alloc - Allocate and initialize a queue structure * @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 count: The number of entries that this queue will handle. * @@ -13946,8 +13947,8 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) * queue on the HBA. **/ struct lpfc_queue * -lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size, - uint32_t entry_count) +lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size, + uint32_t entry_size, uint32_t entry_count) { struct lpfc_queue *queue; struct lpfc_dmabuf *dmabuf; @@ -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; 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) + (sizeof(union sli4_qe) * entry_count), GFP_KERNEL); @@ -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->page_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++) { dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!dmabuf) @@ -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->entry_size = entry_size; - queue->entry_count = entry_count; - queue->phba = phba; INIT_WORK(&queue->irqwork, lpfc_sli4_hba_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, if (!cq || !eq) return -ENODEV; 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); if (!mbox) @@ -14318,8 +14325,8 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, bf_set(lpfc_mbox_hdr_version, &shdr->request, phba->sli4_hba.pc_sli4_params.cqv); 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, 1); + bf_set(lpfc_mbx_cq_create_page_size, &cq_create->u.request, + (cq->page_size / SLI4_PAGE_SIZE)); bf_set(lpfc_cq_eq_id_2, &cq_create->u.request.context, eq->queue_id); } else { @@ -14327,6 +14334,18 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, eq->queue_id); } 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: lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "0361 Unsupported CQ count: " @@ -14352,7 +14371,7 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, break; } 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 = putPaddrLow(dmabuf->phys); 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, numcq = phba->cfg_nvmet_mrq; if (!cqp || !eqp || !numcq) 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); if (!mbox) @@ -14465,6 +14482,8 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp, status = -ENOMEM; goto out; } + if (!phba->sli4_hba.pc_sli4_params.supported) + hw_page_size = cq->page_size; switch (idx) { case 0: @@ -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, &cq_set->u.request, numcq); 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: lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "3118 Bad CQ count. (%d)\n", @@ -14578,6 +14610,7 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp, cq->host_index = 0; cq->hba_index = 0; cq->entry_repost = LPFC_CQ_REPOST; + cq->chann = idx; rc = 0; list_for_each_entry(dmabuf, &cq->page_list, list) { @@ -14872,12 +14905,13 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, void __iomem *bar_memmap_p; uint32_t db_offset; uint16_t pci_barset; + uint8_t wq_create_version; /* sanity check on queue memory */ if (!wq || !cq) return -ENODEV; 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); if (!mbox) @@ -14898,7 +14932,12 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, bf_set(lpfc_mbox_hdr_version, &shdr->request, 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: switch (wq->entry_size) { default: @@ -14956,7 +14995,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, } bf_set(lpfc_mbx_wq_create_page_size, &wq_create->u.request_1, - LPFC_WQ_PAGE_SIZE_4096); + (wq->page_size / SLI4_PAGE_SIZE)); page = wq_create->u.request_1.page; break; default: diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 13b8f4d4da34..301ce46d2d70 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -161,7 +161,6 @@ struct lpfc_queue { #define LPFC_RELEASE_NOTIFICATION_INTERVAL 32 /* For WQs */ 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 */ 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 */ @@ -169,6 +168,11 @@ struct lpfc_queue { struct lpfc_rqb *rqbp; /* ptr to RQ buffers */ 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; #define LPFC_DB_RING_FORMAT 0x01 #define LPFC_DB_LIST_FORMAT 0x02 @@ -769,7 +773,7 @@ int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *, void lpfc_sli4_hba_reset(struct lpfc_hba *); 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 *); 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,