From patchwork Tue Oct 20 20:27:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 287102 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69129C4363A for ; Tue, 20 Oct 2020 20:27:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D62812076A for ; Tue, 20 Oct 2020 20:27:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="IUoRDgaV" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2438472AbgJTU1b (ORCPT ); Tue, 20 Oct 2020 16:27:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2438437AbgJTU1a (ORCPT ); Tue, 20 Oct 2020 16:27:30 -0400 Received: from mail-pg1-x543.google.com (mail-pg1-x543.google.com [IPv6:2607:f8b0:4864:20::543]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 612AAC0613D3 for ; Tue, 20 Oct 2020 13:27:30 -0700 (PDT) Received: by mail-pg1-x543.google.com with SMTP id l18so61644pgg.0 for ; Tue, 20 Oct 2020 13:27:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version; bh=MpWSel5+lfTl4diNlLmpErcbMEH5ronJFUFc4JMgRp4=; b=IUoRDgaVy8mSqTiA/9o601Xt3c1aphmW81mgY+l5fI5LtZL8pRo3wn67USjGkgUo5p JQCFcUux/rElwoPZhX2Q49dj8IPzzd6Q/SsT3Ii/B+8GzKT8XKBl1Hw+Tpw4mWPa4UgQ PCwdKnUdrqMyjeQezO2o5agHLQoUuVWbsZ7M0= 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:mime-version; bh=MpWSel5+lfTl4diNlLmpErcbMEH5ronJFUFc4JMgRp4=; b=eYylvRrdU/lZeSrJf6hSTHjNndMqUkBU2J/DEOSk7MDeHoiRto+lNxkVO7Nw96623D OsL2EsimZgiFnqiFJ9rhfgPX4L+DLUDDCCoB3GyXuaxC8OJ+ZPYP3GaPsXxAxEZYK3l5 osdcWQNf9sK/kYDubA2YL4giIlSKY3CNOeFvvnvyJ6hMkzan+zUP17kEqhZZqZ0T5HDu Q52a4GNTerr9T91H8WL1wQRQTs+rNsy+2J6CYF6AfKzwXdMLYUcBVEUjf7w5UN/VvfW5 EpW4ecCLTckZMzhtYyOK8IVs4/FDcllRBDUY2fRfCSQF1FyKNsH+6RLBRe3ekkaHpy1+ WcDg== X-Gm-Message-State: AOAM531/AQFWy5D8A0rmpXrQZ6DU9V36YYNp+WnXzungG0sI5JLVPcLb YZGdzx1PyDMEwjrJgaDNml56dplB7XxHcGqKfSurnHBZzGhAkiw0Ayfr/ig4Q6J/bvqR9FgpHlr 7YDlrZOWtQBJxQEuNAC1Pc15fI3rUfC07Knu9Ud0MuuDWGc2CYQnHDCmNEUp7EWYhlDNgluCuKQ 3qOxk= X-Google-Smtp-Source: ABdhPJzne3P1IcVyFLfKF4dP1bdAHPC27OThdZEuVGZQduC84H7PhiMa5lqrsRI4iAQ3D1MO6hWonA== X-Received: by 2002:aa7:9048:0:b029:152:883a:9a94 with SMTP id n8-20020aa790480000b0290152883a9a94mr1606942pfo.24.1603225649028; Tue, 20 Oct 2020 13:27:29 -0700 (PDT) Received: from localhost.localdomain ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id b16sm2871404pfp.195.2020.10.20.13.27.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 13:27:28 -0700 (PDT) From: James Smart To: linux-scsi@vger.kernel.org Cc: James Smart , stable@vger.kernel.org, Dick Kennedy Subject: [PATCH 2/9] lpfc: fix scheduling call while in softirq context in lpfc_unreg_rpi Date: Tue, 20 Oct 2020 13:27:12 -0700 Message-Id: <20201020202719.54726-3-james.smart@broadcom.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201020202719.54726-1-james.smart@broadcom.com> References: <20201020202719.54726-1-james.smart@broadcom.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The following call trace was seen during hba reset testing: BUG: scheduling while atomic: swapper/2/0/0x10000100 ... Call Trace: dump_stack+0x19/0x1b __schedule_bug+0x64/0x72 __schedule+0x782/0x840 __cond_resched+0x26/0x30 _cond_resched+0x3a/0x50 mempool_alloc+0xa0/0x170 lpfc_unreg_rpi+0x151/0x630 [lpfc] lpfc_sli_abts_recover_port+0x171/0x190 [lpfc] lpfc_sli4_abts_err_handler+0xb2/0x1f0 [lpfc] lpfc_sli4_io_xri_aborted+0x256/0x300 [lpfc] lpfc_sli4_sp_handle_abort_xri_wcqe.isra.51+0xa3/0x190 [lpfc] lpfc_sli4_fp_handle_cqe+0x89/0x4d0 [lpfc] __lpfc_sli4_process_cq+0xdb/0x2e0 [lpfc] __lpfc_sli4_hba_process_cq+0x41/0x100 [lpfc] lpfc_cq_poll_hdler+0x1a/0x30 [lpfc] irq_poll_softirq+0xc7/0x100 __do_softirq+0xf5/0x280 call_softirq+0x1c/0x30 do_softirq+0x65/0xa0 irq_exit+0x105/0x110 do_IRQ+0x56/0xf0 common_interrupt+0x16a/0x16a With the conversion to blk_io_poll for better interrupt latency in normal cases, it introduced this code path, executed when io aborts or logouts are seen, which attempts to allocate memory for a mailbox command to be issued. The allocation is GFP_KERNEL, thus it could attempt to sleep. Fix by creating a work element that performs the event handling for the remote port. This will have the mailbox commands and other items performed in the work element, not the irq. A much better method as the "irq" routine does not stall while performing all this deep handling code. Ensure that allocation failures are handled and send LOGO on failure. Additionally, enlarged the mailbox memory pool to reduce the possibility of additional allocation in this path. Fixes: 317aeb83c92b ("scsi: lpfc: Add blk_io_poll support for latency improvment") Cc: # v5.9+ Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc.h | 2 +- drivers/scsi/lpfc/lpfc_disc.h | 2 + drivers/scsi/lpfc/lpfc_hbadisc.c | 35 +++++++++++++++++ drivers/scsi/lpfc/lpfc_init.c | 46 +++++++++++++---------- drivers/scsi/lpfc/lpfc_mem.c | 5 ++- drivers/scsi/lpfc/lpfc_nvme.c | 18 ++++++--- drivers/scsi/lpfc/lpfc_sli.c | 64 ++++++++++++++++++++++++++------ drivers/scsi/lpfc/lpfc_sli4.h | 6 +-- 8 files changed, 136 insertions(+), 42 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 549adfaa97ce..93e507677bdc 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -753,7 +753,7 @@ struct lpfc_hba { #define HBA_SP_QUEUE_EVT 0x8 /* Slow-path qevt posted to worker thread*/ #define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */ #define HBA_PERSISTENT_TOPO 0x20 /* Persistent topology support in hba */ -#define ELS_XRI_ABORT_EVENT 0x40 +#define ELS_XRI_ABORT_EVENT 0x40 /* ELS_XRI abort event was queued */ #define ASYNC_EVENT 0x80 #define LINK_DISABLED 0x100 /* Link disabled by user */ #define FCF_TS_INPROG 0x200 /* FCF table scan in progress */ diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 482e4a888dae..1437e44ade80 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -41,6 +41,7 @@ enum lpfc_work_type { LPFC_EVT_DEV_LOSS, LPFC_EVT_FASTPATH_MGMT_EVT, LPFC_EVT_RESET_HBA, + LPFC_EVT_RECOVER_PORT }; /* structure used to queue event to the discovery tasklet */ @@ -128,6 +129,7 @@ struct lpfc_nodelist { struct lpfc_vport *vport; struct lpfc_work_evt els_retry_evt; struct lpfc_work_evt dev_loss_evt; + struct lpfc_work_evt recovery_evt; struct kref kref; atomic_t cmd_pending; uint32_t cmd_qdepth; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 142a02114479..68563f717adf 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -551,6 +551,15 @@ lpfc_work_list_done(struct lpfc_hba *phba) fcf_inuse, nlp_did); break; + case LPFC_EVT_RECOVER_PORT: + ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); + lpfc_sli_abts_recover_port(ndlp->vport, ndlp); + free_evt = 0; + /* decrement the node reference count held for + * this queued work + */ + lpfc_nlp_put(ndlp); + break; case LPFC_EVT_ONLINE: if (phba->link_state < LPFC_LINK_DOWN) *(int *) (evtp->evt_arg1) = lpfc_online(phba); @@ -4487,6 +4496,8 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp); timer_setup(&ndlp->nlp_delayfunc, lpfc_els_retry_delay, 0); + INIT_LIST_HEAD(&ndlp->recovery_evt.evt_listp); + ndlp->nlp_DID = did; ndlp->vport = vport; ndlp->phba = vport->phba; @@ -4984,6 +4995,29 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) mempool_free(mbox, phba->mbox_mem_pool); acc_plogi = 1; } + } else { + lpfc_printf_vlog(vport, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, + "1444 Failed to allocate mempool " + "unreg_rpi UNREG x%x, " + "DID x%x, flag x%x, " + "ndlp x%px\n", + ndlp->nlp_rpi, ndlp->nlp_DID, + ndlp->nlp_flag, ndlp); + + /* Because mempool_alloc failed, we + * will issue a LOGO here and keep the rpi alive if + * not unloading. + */ + if (!(vport->load_flag & FC_UNLOADING)) { + ndlp->nlp_flag &= ~NLP_UNREG_INP; + lpfc_issue_els_logo(vport, ndlp, 0); + ndlp->nlp_prev_state = ndlp->nlp_state; + lpfc_nlp_set_state(vport, ndlp, + NLP_STE_NPR_NODE); + } + + return 1; } lpfc_no_rpi(phba, ndlp); out: @@ -5187,6 +5221,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) list_del_init(&ndlp->els_retry_evt.evt_listp); list_del_init(&ndlp->dev_loss_evt.evt_listp); + list_del_init(&ndlp->recovery_evt.evt_listp); lpfc_cleanup_vports_rrqs(vport, ndlp); if (phba->sli_rev == LPFC_SLI_REV4) ndlp->nlp_flag |= NLP_RELEASE_RPI; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ca25e54bb782..40fe889033d4 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -5958,18 +5958,21 @@ lpfc_sli4_async_grp5_evt(struct lpfc_hba *phba, void lpfc_sli4_async_event_proc(struct lpfc_hba *phba) { struct lpfc_cq_event *cq_event; + unsigned long iflags; /* First, declare the async event has been handled */ - spin_lock_irq(&phba->hbalock); + spin_lock_irqsave(&phba->hbalock, iflags); phba->hba_flag &= ~ASYNC_EVENT; - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags); + /* Now, handle all the async events */ + spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags); while (!list_empty(&phba->sli4_hba.sp_asynce_work_queue)) { - /* Get the first event from the head of the event queue */ - spin_lock_irq(&phba->hbalock); list_remove_head(&phba->sli4_hba.sp_asynce_work_queue, cq_event, struct lpfc_cq_event, list); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, + iflags); + /* Process the asynchronous event */ switch (bf_get(lpfc_trailer_code, &cq_event->cqe.mcqe_cmpl)) { case LPFC_TRAILER_CODE_LINK: @@ -6001,9 +6004,12 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba) &cq_event->cqe.mcqe_cmpl)); break; } + /* Free the completion event processed to the free pool */ lpfc_sli4_cq_event_release(phba, cq_event); + spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags); } + spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags); } /** @@ -6630,6 +6636,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) /* This abort list used by worker thread */ spin_lock_init(&phba->sli4_hba.sgl_list_lock); spin_lock_init(&phba->sli4_hba.nvmet_io_wait_lock); + spin_lock_init(&phba->sli4_hba.asynce_list_lock); + spin_lock_init(&phba->sli4_hba.els_xri_abrt_list_lock); /* * Initialize driver internal slow-path work queues @@ -6641,8 +6649,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) INIT_LIST_HEAD(&phba->sli4_hba.sp_queue_event); /* Asynchronous event CQ Event work queue list */ INIT_LIST_HEAD(&phba->sli4_hba.sp_asynce_work_queue); - /* Fast-path XRI aborted CQ Event work queue list */ - INIT_LIST_HEAD(&phba->sli4_hba.sp_fcp_xri_aborted_work_queue); /* Slow-path XRI aborted CQ Event work queue list */ INIT_LIST_HEAD(&phba->sli4_hba.sp_els_xri_aborted_work_queue); /* Receive queue CQ Event work queue list */ @@ -10174,26 +10180,28 @@ lpfc_sli4_cq_event_release(struct lpfc_hba *phba, static void lpfc_sli4_cq_event_release_all(struct lpfc_hba *phba) { - LIST_HEAD(cqelist); - struct lpfc_cq_event *cqe; + LIST_HEAD(cq_event_list); + struct lpfc_cq_event *cq_event; unsigned long iflags; /* Retrieve all the pending WCQEs from pending WCQE lists */ - spin_lock_irqsave(&phba->hbalock, iflags); - /* Pending FCP XRI abort events */ - list_splice_init(&phba->sli4_hba.sp_fcp_xri_aborted_work_queue, - &cqelist); + /* Pending ELS XRI abort events */ + spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, iflags); list_splice_init(&phba->sli4_hba.sp_els_xri_aborted_work_queue, - &cqelist); + &cq_event_list); + spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, iflags); + /* Pending asynnc events */ + spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags); list_splice_init(&phba->sli4_hba.sp_asynce_work_queue, - &cqelist); - spin_unlock_irqrestore(&phba->hbalock, iflags); + &cq_event_list); + spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags); - while (!list_empty(&cqelist)) { - list_remove_head(&cqelist, cqe, struct lpfc_cq_event, list); - lpfc_sli4_cq_event_release(phba, cqe); + while (!list_empty(&cq_event_list)) { + list_remove_head(&cq_event_list, cq_event, + struct lpfc_cq_event, list); + lpfc_sli4_cq_event_release(phba, cq_event); } } diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 656f35eb853e..79386e294fb9 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -46,6 +46,7 @@ #define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */ #define LPFC_DEVICE_DATA_POOL_SIZE 64 /* max elements in device data pool */ #define LPFC_RRQ_POOL_SIZE 256 /* max elements in non-DMA pool */ +#define LPFC_MBX_POOL_SIZE 256 /* max elements in MBX non-DMA pool */ int lpfc_mem_alloc_active_rrq_pool_s4(struct lpfc_hba *phba) { @@ -111,8 +112,8 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align) pool->current_count++; } - phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MEM_POOL_SIZE, - sizeof(LPFC_MBOXQ_t)); + phba->mbox_mem_pool = mempool_create_kmalloc_pool(LPFC_MBX_POOL_SIZE, + sizeof(LPFC_MBOXQ_t)); if (!phba->mbox_mem_pool) goto fail_free_mbuf_pool; diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index e5be334d6a11..fc39b4ec7b6a 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2280,6 +2280,8 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, int ret, i, pending = 0; struct lpfc_sli_ring *pring; struct lpfc_hba *phba = vport->phba; + struct lpfc_sli4_hdw_queue *qp; + int abts_scsi, abts_nvme; /* Host transport has to clean up and confirm requiring an indefinite * wait. Print a message if a 10 second wait expires and renew the @@ -2290,17 +2292,23 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, ret = wait_for_completion_timeout(lport_unreg_cmp, wait_tmo); if (unlikely(!ret)) { pending = 0; + abts_scsi = 0; + abts_nvme = 0; for (i = 0; i < phba->cfg_hdw_queue; i++) { - pring = phba->sli4_hba.hdwq[i].io_wq->pring; + qp = &phba->sli4_hba.hdwq[i]; + pring = qp->io_wq->pring; if (!pring) continue; - if (pring->txcmplq_cnt) - pending += pring->txcmplq_cnt; + pending += pring->txcmplq_cnt; + abts_scsi += qp->abts_scsi_io_bufs; + abts_nvme += qp->abts_nvme_io_bufs; } lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6176 Lport x%px Localport x%px wait " - "timed out. Pending %d. Renewing.\n", - lport, vport->localport, pending); + "timed out. Pending %d [%d:%d]. " + "Renewing.\n", + lport, vport->localport, pending, + abts_scsi, abts_nvme); continue; } break; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 4958bb0f2c97..497b5ca34b14 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -10370,6 +10370,32 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) return 0; } +static void +lpfc_sli_post_recovery_event(struct lpfc_hba *phba, + struct lpfc_nodelist *ndlp) +{ + unsigned long iflags; + struct lpfc_work_evt *evtp = &ndlp->recovery_evt; + + spin_lock_irqsave(&phba->hbalock, iflags); + if (!list_empty(&evtp->evt_listp)) { + spin_unlock_irqrestore(&phba->hbalock, iflags); + return; + } + + /* Incrementing the reference count until the queued work is done. */ + evtp->evt_arg1 = lpfc_nlp_get(ndlp); + if (!evtp->evt_arg1) { + spin_unlock_irqrestore(&phba->hbalock, iflags); + return; + } + evtp->evt = LPFC_EVT_RECOVER_PORT; + list_add_tail(&evtp->evt_listp, &phba->work_list); + spin_unlock_irqrestore(&phba->hbalock, iflags); + + lpfc_worker_wake_up(phba); +} + /* lpfc_sli_abts_err_handler - handle a failed ABTS request from an SLI3 port. * @phba: Pointer to HBA context object. * @iocbq: Pointer to iocb object. @@ -10460,7 +10486,7 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba, ext_status = axri->parameter & IOERR_PARAM_MASK; if ((bf_get(lpfc_wcqe_xa_status, axri) == IOSTAT_LOCAL_REJECT) && ((ext_status == IOERR_SEQUENCE_TIMEOUT) || (ext_status == 0))) - lpfc_sli_abts_recover_port(vport, ndlp); + lpfc_sli_post_recovery_event(phba, ndlp); } /** @@ -13068,23 +13094,30 @@ lpfc_sli_intr_handler(int irq, void *dev_id) void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba) { struct lpfc_cq_event *cq_event; + unsigned long iflags; /* First, declare the els xri abort event has been handled */ - spin_lock_irq(&phba->hbalock); + spin_lock_irqsave(&phba->hbalock, iflags); phba->hba_flag &= ~ELS_XRI_ABORT_EVENT; - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags); + /* Now, handle all the els xri abort events */ + spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, iflags); while (!list_empty(&phba->sli4_hba.sp_els_xri_aborted_work_queue)) { /* Get the first event from the head of the event queue */ - spin_lock_irq(&phba->hbalock); list_remove_head(&phba->sli4_hba.sp_els_xri_aborted_work_queue, cq_event, struct lpfc_cq_event, list); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, + iflags); /* Notify aborted XRI for ELS work queue */ lpfc_sli4_els_xri_aborted(phba, &cq_event->cqe.wcqe_axri); + /* Free the event processed back to the free pool */ lpfc_sli4_cq_event_release(phba, cq_event); + spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, + iflags); } + spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, iflags); } /** @@ -13295,9 +13328,13 @@ lpfc_sli4_sp_handle_async_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe) cq_event = lpfc_cq_event_setup(phba, mcqe, sizeof(struct lpfc_mcqe)); if (!cq_event) return false; - spin_lock_irqsave(&phba->hbalock, iflags); + + spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags); list_add_tail(&cq_event->list, &phba->sli4_hba.sp_asynce_work_queue); + spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags); + /* Set the async event flag */ + spin_lock_irqsave(&phba->hbalock, iflags); phba->hba_flag |= ASYNC_EVENT; spin_unlock_irqrestore(&phba->hbalock, iflags); @@ -13572,17 +13609,20 @@ lpfc_sli4_sp_handle_abort_xri_wcqe(struct lpfc_hba *phba, break; case LPFC_NVME_LS: /* NVME LS uses ELS resources */ case LPFC_ELS: - cq_event = lpfc_cq_event_setup( - phba, wcqe, sizeof(struct sli4_wcqe_xri_aborted)); - if (!cq_event) - return false; + cq_event = lpfc_cq_event_setup(phba, wcqe, sizeof(*wcqe)); + if (!cq_event) { + workposted = false; + break; + } cq_event->hdwq = cq->hdwq; - spin_lock_irqsave(&phba->hbalock, iflags); + spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, + iflags); list_add_tail(&cq_event->list, &phba->sli4_hba.sp_els_xri_aborted_work_queue); /* Set the els xri abort event flag */ phba->hba_flag |= ELS_XRI_ABORT_EVENT; - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, + iflags); workposted = true; break; default: diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index a966cdeb52ee..100cb1a94811 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -920,8 +920,9 @@ struct lpfc_sli4_hba { struct list_head sp_queue_event; struct list_head sp_cqe_event_pool; struct list_head sp_asynce_work_queue; - struct list_head sp_fcp_xri_aborted_work_queue; + spinlock_t asynce_list_lock; /* protect sp_asynce_work_queue list */ struct list_head sp_els_xri_aborted_work_queue; + spinlock_t els_xri_abrt_list_lock; /* protect els_xri_aborted list */ struct list_head sp_unsol_work_queue; struct lpfc_sli4_link link_state; struct lpfc_sli4_lnk_info lnk_info; @@ -1103,8 +1104,7 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *); void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *); int lpfc_sli4_resume_rpi(struct lpfc_nodelist *, void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *); -void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *); -void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *); +void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba); void lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, struct sli4_wcqe_xri_aborted *axri, struct lpfc_io_buf *lpfc_ncmd); From patchwork Tue Oct 20 20:27:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 287101 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 299F7C388F7 for ; Tue, 20 Oct 2020 20:27:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C26C72076A for ; Tue, 20 Oct 2020 20:27:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="hU6518vl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2438479AbgJTU1e (ORCPT ); Tue, 20 Oct 2020 16:27:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2438474AbgJTU1c (ORCPT ); Tue, 20 Oct 2020 16:27:32 -0400 Received: from mail-pg1-x543.google.com (mail-pg1-x543.google.com [IPv6:2607:f8b0:4864:20::543]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB200C0613CE for ; Tue, 20 Oct 2020 13:27:32 -0700 (PDT) Received: by mail-pg1-x543.google.com with SMTP id o7so42505pgv.6 for ; Tue, 20 Oct 2020 13:27:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version; bh=GRWsV8c7/ylozzxjieOFe3NBOPCGJE0vk589ySlb8m4=; b=hU6518vl65TnBdIbWHUn4iMDRQ1AzZCxB6HTcv4XLCPtNB5qWUrWS771mRVRZ6GJF8 azThd6lOTYMaBKMKeG7k2pkwZ+5qWXru/S3j1bP/nX03S44ds7Itzlbs7FOGpac4R1zv ydbCVmvKnVVhglPOdXhekyd/O0iNYhvoCakdY= 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:mime-version; bh=GRWsV8c7/ylozzxjieOFe3NBOPCGJE0vk589ySlb8m4=; b=pNX21dM1m5RhI6q/DErcm6hfk9obyRr2yjJHRQSWQFo3anKP6BhDYccrbdOh8oe2Hx C2Cm5jWdYrZR7iq6K1MW5TvuwukDoU8bUz9HxAXCotQ1bkvJF6PhqmCynE9F1hsYg9Ki gdvQGNuU0pqkKP6HeNXalsip3bxIPzthevptWE8Gmyy/OtIPV2ee9lOlfyantbWXa2ZR jn6vT0nleYRCS/IPOljm2Ajt/rb7BTfGRSLLwAnMH3lYWjP4WGb9hOjG+4bRB3qHMkfS PsRX7A/O/xT3LUsbUs8zUH//alfdPk5kkHaQkXUgE/r5HKW2nDvJSxHf4kWS3ttpq8Gp BS5Q== X-Gm-Message-State: AOAM531Rz7X9W71oyNuOpA8Djs2T9jnfiGixl5E3+h2lyGNgPcfmZ+t3 6pBVeE5vgUfVF4ROVi1Yrzjv41rmC+J6bcklDk0I9pwrJrQ7bWk3m296rCxO+lMOSXNJS29fD0s C5PR7ySCTcHZS2MEjVOq7xT1ztXC1CADZUH1YjGmMrW7ahqXheJK56FKIZidORdt17z/C+0gKWC H/mWM= X-Google-Smtp-Source: ABdhPJxVucYvzZC55j3AEcUJJ+M/Gke2sdQQeG1ZQfcKX0SNvI7aTpJ/5zKC1p7YNDymlMAGO2xqzw== X-Received: by 2002:a62:7d15:0:b029:155:29ed:db4c with SMTP id y21-20020a627d150000b029015529eddb4cmr1595188pfc.77.1603225651463; Tue, 20 Oct 2020 13:27:31 -0700 (PDT) Received: from localhost.localdomain ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id b16sm2871404pfp.195.2020.10.20.13.27.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 13:27:30 -0700 (PDT) From: James Smart To: linux-scsi@vger.kernel.org Cc: James Smart Subject: [PATCH 4/9] lpfc: Removed unused macros in lpfc_attr.c. Date: Tue, 20 Oct 2020 13:27:14 -0700 Message-Id: <20201020202719.54726-5-james.smart@broadcom.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201020202719.54726-1-james.smart@broadcom.com> References: <20201020202719.54726-1-james.smart@broadcom.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Removed unused MRQ-related defines that are not referenced. Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_attr.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index e94eac194676..2d810474875c 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -57,10 +57,6 @@ #define LPFC_MIN_DEVLOSS_TMO 1 #define LPFC_MAX_DEVLOSS_TMO 255 -#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 * make sure that library write key is also changed. From patchwork Tue Oct 20 20:27:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 287100 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08B9CC54FB2 for ; Tue, 20 Oct 2020 20:27:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9F82C2225D for ; Tue, 20 Oct 2020 20:27:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="hhEsgYwx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2438482AbgJTU1f (ORCPT ); Tue, 20 Oct 2020 16:27:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2438446AbgJTU1f (ORCPT ); Tue, 20 Oct 2020 16:27:35 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2279FC0613CE for ; Tue, 20 Oct 2020 13:27:35 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id t14so58320pgg.1 for ; Tue, 20 Oct 2020 13:27:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version; bh=SWAoL3y/nIYTS+7Oz19qc+RqAeJctl7s60ElHegbSEU=; b=hhEsgYwxvbGJdQpVmhKSYzrtnc1D6rdneRroqSPUYCbrrIWVdTMxlbygt+PXyjLHIA PXicr0wQdUHf6Vuze4wdJ+itcY7dyARNErYSIQ8HM+LVn0pbgjkJDZzEHpL4kV00VYp4 1phlAnw9rQDV5shejkFL3iMs7wQ0lx9hsnxQE= 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:mime-version; bh=SWAoL3y/nIYTS+7Oz19qc+RqAeJctl7s60ElHegbSEU=; b=cBpvJyi/t+Yyy6AupHYiEhsPJa045wuOZVYLZIxIhdk1bUvx/l1gh/fZWMFp3uYydz RQFWTJtpFeIFcfKWOq9vvYmUbc2OPu6vbo6eUsvAjbS62xUfUD1vNwsefUahovvog6r5 WmYFhOFocTRKvfWA0j+iSVY2mX2D8lBeq6ZVbDEelw+Gs9nT1OepK2B1bLrlsIwy9zUP NdHDq+YKW5HHQOVjqe9kW6A/xTT7zj7ZOb4pcQsEMJPuBYMbGMVrMIiqCJCrqVkD5j11 sqt82Zei/U92BVXR9rJ7dzVOdiFt4pf9PB9kCAuEIUCV0SWxsCo+lZbgbMIzC7rUnZS8 kM8A== X-Gm-Message-State: AOAM533vQ897eYJSDvxhf743I+41Ncws4y0dPg76a7ygmgi1GavPbJiK 3m7fl5B7tZngvJalDnREs4tWYydsl/+ikDctESGlpjELJMyC9TahHU9kylAJDQdgHrLfepRfi9O IZY4qLxUO55sLbkwcvID0GNvMlT8vYrMlTTK+wQ5I/LzARdD6h1YIDC898JuN83AL2IwC35JD1b yCOiQ= X-Google-Smtp-Source: ABdhPJx0ao9sUjnsvKgquPJBgvoSpWRveiHmk14KTffelk4WMclEtK6IOwU20wUwm5FZji5yanI7xA== X-Received: by 2002:a63:c55:: with SMTP id 21mr77618pgm.392.1603225654082; Tue, 20 Oct 2020 13:27:34 -0700 (PDT) Received: from localhost.localdomain ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id b16sm2871404pfp.195.2020.10.20.13.27.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 13:27:33 -0700 (PDT) From: James Smart To: linux-scsi@vger.kernel.org Cc: James Smart Subject: [PATCH 6/9] lpfc: Enlarge max_sectors in scsi templates Date: Tue, 20 Oct 2020 13:27:16 -0700 Message-Id: <20201020202719.54726-7-james.smart@broadcom.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201020202719.54726-1-james.smart@broadcom.com> References: <20201020202719.54726-1-james.smart@broadcom.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The driver supports arbitrarily large sgl lists and the current value for max_sectors is limiting. Change the max_sectors value to the largest value. This was actually done prior but it only corrected one template and that template was later removed. So change the remaining 2 templates. Other areas which hard-set the sectors value should be inheriting what is in the template. Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_init.c | 5 +---- drivers/scsi/lpfc/lpfc_scsi.c | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 40fe889033d4..d2c172348065 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4343,16 +4343,13 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) /* Seed physical port template */ memcpy(template, &lpfc_template, sizeof(*template)); - if (use_no_reset_hba) { + if (use_no_reset_hba) /* template is for a no reset SCSI Host */ - template->max_sectors = 0xffff; template->eh_host_reset_handler = NULL; - } /* Template for all vports this physical port creates */ memcpy(&phba->vport_template, &lpfc_template, sizeof(*template)); - phba->vport_template.max_sectors = 0xffff; phba->vport_template.shost_attrs = lpfc_vport_attrs; phba->vport_template.eh_bus_reset_handler = NULL; phba->vport_template.eh_host_reset_handler = NULL; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 5e802c8b22a9..87f481b14d83 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -6029,7 +6029,7 @@ struct scsi_host_template lpfc_template_nvme = { .sg_tablesize = 1, .cmd_per_lun = 1, .shost_attrs = lpfc_hba_attrs, - .max_sectors = 0xFFFF, + .max_sectors = 0xFFFFFFFF, .vendor_id = LPFC_NL_VENDOR_ID, .track_queue_depth = 0, }; @@ -6054,7 +6054,7 @@ struct scsi_host_template lpfc_template = { .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, .cmd_per_lun = LPFC_CMD_PER_LUN, .shost_attrs = lpfc_hba_attrs, - .max_sectors = 0xFFFF, + .max_sectors = 0xFFFFFFFF, .vendor_id = LPFC_NL_VENDOR_ID, .change_queue_depth = scsi_change_queue_depth, .track_queue_depth = 1, From patchwork Tue Oct 20 20:27:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 287099 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAF01C41604 for ; Tue, 20 Oct 2020 20:27:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 85A252076A for ; Tue, 20 Oct 2020 20:27:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="UU0HIyL2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2438483AbgJTU1i (ORCPT ); Tue, 20 Oct 2020 16:27:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39280 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2438481AbgJTU1i (ORCPT ); Tue, 20 Oct 2020 16:27:38 -0400 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27E89C0613CE for ; Tue, 20 Oct 2020 13:27:38 -0700 (PDT) Received: by mail-pg1-x533.google.com with SMTP id j7so45606pgk.5 for ; Tue, 20 Oct 2020 13:27:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version; bh=CHTW+PsRF5FB59I3e5ygYbg/8stoN+CHgQHp2Pq9gF8=; b=UU0HIyL2G4Jlu162tlWwUyRXikmiaf3ptc/aUhT1Mgg3WoPBAegfGAmkwkKHSCKkRo pNBs77U/UW33Nfl48M5tp7s1zgbVK+WI1EGY3tys1mEXkFFbtcHdGY5OioiaHhGQp+/y imFJG+QcuYIB3hY4umG5h9PeJ0unQxGxwF9E8= 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:mime-version; bh=CHTW+PsRF5FB59I3e5ygYbg/8stoN+CHgQHp2Pq9gF8=; b=gT1KRtinkc2MNpKBrBZZfpNWn91vcIYVYDTnpBsxfJIvlOUhW+gztO1eAo+fSb8Xr2 M2Taa45Zr8CtXB8JxlNkdkHeUI/kGV/JwMkGUwxgSDfjXwVQvqaMv4RaojBsaXgWghFx L2eLPErLovIwu7jFMI+BdR+keGbtxvdA6IBSU0QwWXTiwRWgixDJZ/70EcWUpb6eI+pe QxzgemBEe0buqI5whcv2y1TD3GAMa38QEEG69+nVgG0xRD6uBczwDwbWo5zMpQBXlFtI 7gf84x/UzOpa4CIPIZ9d9FsIz1DiLa433oKzgZymyAy/EiRT8mmTVGZo0TRjcnfZOQmu Pz5g== X-Gm-Message-State: AOAM533Swyj1M23jMHXcszttFpV9h+O4aFOCCCPTd+YaRC1xmQyLRZqM ZuMHWLGSgtifN/PB5oPe1jMMVdgBR2qp80vvUaZDbui1U/KqNYyHCZHStx6xViBKiVXektfHHqq 4UdmX3iEqLBNoxx3rAuNPFa28CfUv7RaK+Z6S30b71nM5ayy0Q3Fz+SArxm2LfwBqJAMMeozH+K 3+u2w= X-Google-Smtp-Source: ABdhPJwrg1RfHCoYZ4hhPtGduz91klKL9TDxlDt0cHSEdIzZ3gCzjh8yFzUXxnX2Tw2BZ8HtfqHiKw== X-Received: by 2002:a63:4e5e:: with SMTP id o30mr64940pgl.251.1603225656799; Tue, 20 Oct 2020 13:27:36 -0700 (PDT) Received: from localhost.localdomain ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id b16sm2871404pfp.195.2020.10.20.13.27.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Oct 2020 13:27:36 -0700 (PDT) From: James Smart To: linux-scsi@vger.kernel.org Cc: James Smart , Dick Kennedy Subject: [PATCH 8/9] lpfc: Reject CT request for MIB commands Date: Tue, 20 Oct 2020 13:27:18 -0700 Message-Id: <20201020202719.54726-9-james.smart@broadcom.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201020202719.54726-1-james.smart@broadcom.com> References: <20201020202719.54726-1-james.smart@broadcom.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Now that MIB support was registered with FDMI, the driver may receive CT requests for MIB-related commands. At this time, no command is supported. However, the driver needs to be graceful and reject the CT request. This patch adds identification of the requests as well as sending the reject response. Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_bsg.c | 21 +-- drivers/scsi/lpfc/lpfc_ct.c | 311 ++++++++++++++++++++++++++++++++--- drivers/scsi/lpfc/lpfc_hw.h | 3 + 3 files changed, 296 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 6f9d648a9b9c..5b66b8ea8363 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -939,28 +939,9 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, INIT_LIST_HEAD(&head); list_add_tail(&head, &piocbq->list); - if (piocbq->iocb.ulpBdeCount == 0 || - piocbq->iocb.un.cont64[0].tus.f.bdeSize == 0) - goto error_ct_unsol_exit; - - if (phba->link_state == LPFC_HBA_ERROR || - (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE))) - goto error_ct_unsol_exit; - - if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) - dmabuf = bdeBuf1; - else { - dma_addr = getPaddr(piocbq->iocb.un.cont64[0].addrHigh, - piocbq->iocb.un.cont64[0].addrLow); - dmabuf = lpfc_sli_ringpostbuf_get(phba, pring, dma_addr); - } - if (dmabuf == NULL) - goto error_ct_unsol_exit; - ct_req = (struct lpfc_sli_ct_request *)dmabuf->virt; + ct_req = (struct lpfc_sli_ct_request *)bdeBuf1; evt_req_id = ct_req->FsType; cmd = ct_req->CommandResponse.bits.CmdRsp; - if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) - lpfc_sli_ringpostbuf_put(phba, pring, dmabuf); spin_lock_irqsave(&phba->ct_ev_lock, flags); list_for_each_entry(evt, &phba->ct_ev_waiters, node) { diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index bff7d0b3ce7b..d7811fa2407c 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -99,21 +99,265 @@ lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size); } +/** + * lpfc_ct_unsol_cmpl : Completion callback function for unsol ct commands + * @phba : pointer to lpfc hba data structure. + * @cmdiocb : pointer to lpfc command iocb data structure. + * @rspiocb : pointer to lpfc response iocb data structure. + * + * This routine is the callback function for issuing unsol ct reject command. + * The memory allocated in the reject command path is freed up here. + **/ +static void +lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_iocbq *rspiocb) +{ + struct lpfc_nodelist *ndlp; + struct lpfc_dmabuf *mp, *bmp; + + ndlp = (struct lpfc_nodelist *)cmdiocb->context1; + if (ndlp) + lpfc_nlp_put(ndlp); + + mp = cmdiocb->context2; + bmp = cmdiocb->context3; + if (mp) { + lpfc_mbuf_free(phba, mp->virt, mp->phys); + kfree(mp); + cmdiocb->context2 = NULL; + } + + if (bmp) { + lpfc_mbuf_free(phba, bmp->virt, bmp->phys); + kfree(bmp); + cmdiocb->context3 = NULL; + } + + lpfc_sli_release_iocbq(phba, cmdiocb); +} + +/** + * lpfc_ct_reject_event : Issue reject for unhandled CT MIB commands + * @ndlp : pointer to a node-list data structure. + * ct_req : pointer to the CT request data structure. + * rx_id : rx_id of the received UNSOL CT command + * ox_id : ox_id of the UNSOL CT command + * + * This routine is invoked by the lpfc_ct_handle_mibreq routine for sending + * a reject response. Reject response is sent for the unhandled commands. + **/ +static void +lpfc_ct_reject_event(struct lpfc_nodelist *ndlp, + struct lpfc_sli_ct_request *ct_req, + u16 rx_id, u16 ox_id) +{ + struct lpfc_vport *vport = ndlp->vport; + struct lpfc_hba *phba = vport->phba; + struct lpfc_sli_ct_request *ct_rsp; + struct lpfc_iocbq *cmdiocbq = NULL; + struct lpfc_dmabuf *bmp = NULL; + struct lpfc_dmabuf *mp = NULL; + struct ulp_bde64 *bpl; + IOCB_t *icmd; + u8 rc = 0; + + /* fill in BDEs for command */ + mp = kmalloc(sizeof(*mp), GFP_KERNEL); + if (!mp) { + rc = 1; + goto ct_exit; + } + + mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &mp->phys); + if (!mp->virt) { + rc = 2; + goto ct_free_mp; + } + + /* Allocate buffer for Buffer ptr list */ + bmp = kmalloc(sizeof(*bmp), GFP_KERNEL); + if (!bmp) { + rc = 3; + goto ct_free_mpvirt; + } + + bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &bmp->phys); + if (!bmp->virt) { + rc = 4; + goto ct_free_bmp; + } + + INIT_LIST_HEAD(&mp->list); + INIT_LIST_HEAD(&bmp->list); + + bpl = (struct ulp_bde64 *)bmp->virt; + memset(bpl, 0, sizeof(struct ulp_bde64)); + bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys)); + bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys)); + bpl->tus.f.bdeFlags = BUFF_TYPE_BLP_64; + bpl->tus.f.bdeSize = (LPFC_CT_PREAMBLE - 4); + bpl->tus.w = le32_to_cpu(bpl->tus.w); + + ct_rsp = (struct lpfc_sli_ct_request *)mp->virt; + memset(ct_rsp, 0, sizeof(struct lpfc_sli_ct_request)); + + ct_rsp->RevisionId.bits.Revision = SLI_CT_REVISION; + ct_rsp->RevisionId.bits.InId = 0; + ct_rsp->FsType = ct_req->FsType; + ct_rsp->FsSubType = ct_req->FsSubType; + ct_rsp->CommandResponse.bits.Size = 0; + ct_rsp->CommandResponse.bits.CmdRsp = + cpu_to_be16(SLI_CT_RESPONSE_FS_RJT); + ct_rsp->ReasonCode = SLI_CT_REQ_NOT_SUPPORTED; + ct_rsp->Explanation = SLI_CT_NO_ADDITIONAL_EXPL; + + cmdiocbq = lpfc_sli_get_iocbq(phba); + if (!cmdiocbq) { + rc = 5; + goto ct_free_bmpvirt; + } + + icmd = &cmdiocbq->iocb; + icmd->un.genreq64.bdl.ulpIoTag32 = 0; + icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys); + icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys); + icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; + icmd->un.genreq64.bdl.bdeSize = sizeof(struct ulp_bde64); + icmd->un.genreq64.w5.hcsw.Fctl = (LS | LA); + icmd->un.genreq64.w5.hcsw.Dfctl = 0; + icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_SOL_CTL; + icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT; + icmd->ulpCommand = CMD_XMIT_SEQUENCE64_CX; + icmd->ulpBdeCount = 1; + icmd->ulpLe = 1; + icmd->ulpClass = CLASS3; + + /* Save for completion so we can release these resources */ + cmdiocbq->context1 = lpfc_nlp_get(ndlp); + cmdiocbq->context2 = (uint8_t *)mp; + cmdiocbq->context3 = (uint8_t *)bmp; + cmdiocbq->iocb_cmpl = lpfc_ct_unsol_cmpl; + icmd->ulpContext = rx_id; /* Xri / rx_id */ + icmd->unsli3.rcvsli3.ox_id = ox_id; + icmd->un.ulpWord[3] = + phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; + icmd->ulpTimeout = (3 * phba->fc_ratov); + + cmdiocbq->retry = 0; + cmdiocbq->vport = vport; + cmdiocbq->context_un.ndlp = NULL; + cmdiocbq->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; + + rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0); + if (!rc) + return; + + rc = 6; + lpfc_nlp_put(ndlp); + lpfc_sli_release_iocbq(phba, cmdiocbq); +ct_free_bmpvirt: + lpfc_mbuf_free(phba, bmp->virt, bmp->phys); +ct_free_bmp: + kfree(bmp); +ct_free_mpvirt: + lpfc_mbuf_free(phba, mp->virt, mp->phys); +ct_free_mp: + kfree(mp); +ct_exit: + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "6440 Unsol CT: Rsp err %d Data: x%x\n", + rc, vport->fc_flag); +} + +/** + * lpfc_ct_handle_mibreq - Process an unsolicited CT MIB request data buffer + * @phba: pointer to lpfc hba data structure. + * @ctiocb: pointer to lpfc CT command iocb data structure. + * + * This routine is used for processing the IOCB associated with a unsolicited + * CT MIB request. It first determines whether there is an existing ndlp that + * matches the DID from the unsolicited IOCB. If not, it will return. + **/ +static void +lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq) +{ + struct lpfc_sli_ct_request *ct_req; + struct lpfc_nodelist *ndlp = NULL; + struct lpfc_vport *vport = NULL; + IOCB_t *icmd = &ctiocbq->iocb; + u32 mi_cmd, vpi; + u32 did = 0; + + vpi = ctiocbq->iocb.unsli3.rcvsli3.vpi; + vport = lpfc_find_vport_by_vpid(phba, vpi); + if (!vport) { + lpfc_printf_log(phba, KERN_INFO, LOG_ELS, + "6437 Unsol CT: VPORT NULL vpi : x%x\n", + vpi); + return; + } + + did = ctiocbq->iocb.un.rcvels.remoteID; + if (icmd->ulpStatus) { + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "6438 Unsol CT: status:x%x/x%x did : x%x\n", + icmd->ulpStatus, icmd->un.ulpWord[4], did); + return; + } + + /* Ignore traffic received during vport shutdown */ + if (vport->fc_flag & FC_UNLOADING) + return; + + ndlp = lpfc_findnode_did(vport, did); + if (!ndlp) { + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "6439 Unsol CT: NDLP Not Found for DID : x%x", + did); + return; + } + + ct_req = ((struct lpfc_sli_ct_request *) + (((struct lpfc_dmabuf *)ctiocbq->context2)->virt)); + + mi_cmd = ct_req->CommandResponse.bits.CmdRsp; + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "6442 : MI Cmd : x%x Not Supported\n", mi_cmd); + lpfc_ct_reject_event(ndlp, ct_req, + ctiocbq->iocb.ulpContext, + ctiocbq->iocb.unsli3.rcvsli3.ox_id); +} + +/** + * lpfc_ct_unsol_event - Process an unsolicited event from a ct sli ring + * @phba: pointer to lpfc hba data structure. + * @pring: pointer to a SLI ring. + * @ctiocbq: pointer to lpfc ct iocb data structure. + * + * This routine is used to process an unsolicited event received from a SLI + * (Service Level Interface) ring. The actual processing of the data buffer + * associated with the unsolicited event is done by invoking appropriate routine + * after properly set up the iocb buffer from the SLI ring on which the + * unsolicited event was received. + **/ void lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, - struct lpfc_iocbq *piocbq) + struct lpfc_iocbq *ctiocbq) { struct lpfc_dmabuf *mp = NULL; - IOCB_t *icmd = &piocbq->iocb; + IOCB_t *icmd = &ctiocbq->iocb; int i; struct lpfc_iocbq *iocbq; - dma_addr_t paddr; + dma_addr_t dma_addr; uint32_t size; struct list_head head; - struct lpfc_dmabuf *bdeBuf; + struct lpfc_sli_ct_request *ct_req; + struct lpfc_dmabuf *bdeBuf1 = ctiocbq->context2; + struct lpfc_dmabuf *bdeBuf2 = ctiocbq->context3; - if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0) - return; + ctiocbq->context1 = NULL; + ctiocbq->context2 = NULL; + ctiocbq->context3 = NULL; if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); @@ -127,46 +371,75 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, return; } - /* If there are no BDEs associated with this IOCB, - * there is nothing to do. + /* If there are no BDEs associated + * with this IOCB, there is nothing to do. */ if (icmd->ulpBdeCount == 0) return; + if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { + ctiocbq->context2 = bdeBuf1; + if (icmd->ulpBdeCount == 2) + ctiocbq->context3 = bdeBuf2; + } else { + dma_addr = getPaddr(icmd->un.cont64[0].addrHigh, + icmd->un.cont64[0].addrLow); + ctiocbq->context2 = lpfc_sli_ringpostbuf_get(phba, pring, + dma_addr); + if (icmd->ulpBdeCount == 2) { + dma_addr = getPaddr(icmd->un.cont64[1].addrHigh, + icmd->un.cont64[1].addrLow); + ctiocbq->context3 = lpfc_sli_ringpostbuf_get(phba, + pring, + dma_addr); + } + } + + ct_req = ((struct lpfc_sli_ct_request *) + (((struct lpfc_dmabuf *)ctiocbq->context2)->virt)); + + if (ct_req->FsType == SLI_CT_MANAGEMENT_SERVICE && + ct_req->FsSubType == SLI_CT_MIB_Subtypes) { + lpfc_ct_handle_mibreq(phba, ctiocbq); + } else { + if (!lpfc_bsg_ct_unsol_event(phba, pring, ctiocbq)) + return; + } + if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { INIT_LIST_HEAD(&head); - list_add_tail(&head, &piocbq->list); + list_add_tail(&head, &ctiocbq->list); list_for_each_entry(iocbq, &head, list) { icmd = &iocbq->iocb; if (icmd->ulpBdeCount == 0) continue; - bdeBuf = iocbq->context2; + bdeBuf1 = iocbq->context2; iocbq->context2 = NULL; size = icmd->un.cont64[0].tus.f.bdeSize; - lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size); - lpfc_in_buf_free(phba, bdeBuf); + lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf1, size); + lpfc_in_buf_free(phba, bdeBuf1); if (icmd->ulpBdeCount == 2) { - bdeBuf = iocbq->context3; + bdeBuf2 = iocbq->context3; iocbq->context3 = NULL; size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize; - lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, + lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf2, size); - lpfc_in_buf_free(phba, bdeBuf); + lpfc_in_buf_free(phba, bdeBuf2); } } list_del(&head); } else { INIT_LIST_HEAD(&head); - list_add_tail(&head, &piocbq->list); + list_add_tail(&head, &ctiocbq->list); list_for_each_entry(iocbq, &head, list) { icmd = &iocbq->iocb; if (icmd->ulpBdeCount == 0) lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0); for (i = 0; i < icmd->ulpBdeCount; i++) { - paddr = getPaddr(icmd->un.cont64[i].addrHigh, - icmd->un.cont64[i].addrLow); + dma_addr = getPaddr(icmd->un.cont64[i].addrHigh, + icmd->un.cont64[i].addrLow); mp = lpfc_sli_ringpostbuf_get(phba, pring, - paddr); + dma_addr); size = icmd->un.cont64[i].tus.f.bdeSize; lpfc_ct_unsol_buffer(phba, iocbq, mp, size); lpfc_in_buf_free(phba, mp); diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 28b8a394f796..42682d95af52 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1380,6 +1380,9 @@ struct lpfc_fdmi_reg_hba { struct lpfc_fdmi_reg_port_list rpl; }; +/******** MI MIB ********/ +#define SLI_CT_MIB_Subtypes 0x11 + /* * Register HBA Attributes (RHAT) */