From patchwork Sun Oct 29 01:14:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 10031199 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 D8DDD60249 for ; Sun, 29 Oct 2017 01:15:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA78D2883D for ; Sun, 29 Oct 2017 01:15:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF5732888D; Sun, 29 Oct 2017 01:15:13 +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=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM 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 4BF012883D for ; Sun, 29 Oct 2017 01:15:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751801AbdJ2BPM (ORCPT ); Sat, 28 Oct 2017 21:15:12 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:56803 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751582AbdJ2BPI (ORCPT ); Sat, 28 Oct 2017 21:15:08 -0400 Received: by mail-pg0-f68.google.com with SMTP id m18so8227016pgd.13 for ; Sat, 28 Oct 2017 18:15:07 -0700 (PDT) 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=yjanQ07AXZsxiUeeSEy91bMgAkrFSvgrvuu8hdfPaQY=; b=mhEovz5LGP6NpbDBd+73DM2kYMvur4huchWHXiJp1mbRxQQzfnQV5FjXVkJsGazUzf 6GeeieUxwB6MFtt5jyjeOyI/A1tRg0ZRSidr/V/DYWm0qDFFwkYyOYmFTPFSAmFkn1X6 wI0F9dOTue/xzp3Y1cyD5P8pG17OYbSIZ56A0EUk8myk5S+r4yhn4eYD0iDEauL+XPr4 bah3///5RnNjMwabmdBpfcgKAWtMkfQzPq+iQwoeVhUO/7TV9c1VqHypM6bKCQvuricB 0lC9TK2OgYJmJf7b2TltVfoYFOc36cLCpZnlEdNAd/0ArjWinYZhQtmHs4FVyKNcICfj kB3A== 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=yjanQ07AXZsxiUeeSEy91bMgAkrFSvgrvuu8hdfPaQY=; b=Eqacuo8UNotinK/AyJDA5ReyTPgxFV7CwaQE8SKoK20NVNVtOuJsbtFods2BlZFbXh vDI+dAO3B0ncUmi79EpAHmxDEc6vVFnVhrv1U/PCaSetR2skQG4IR+Ju60oZDUvzEKqv 3LBUVGPwLIeBOFAaSRsxMlDvT/+WOZR6y+AzsbLD61g3+8X1mwqhdDkHeqsveYU3dobu NTLlsMP/HytDZ2l/zHpPXApP71UrSM+Gx5U/YYywUF5m5T8bZf8hI35lmv52eUwjNwuQ Q+Esg9JbpvoupUe5m+yjI/vBwGX+MNZG4h3+NMc0fuLO5eo6pmC4MwdjeFtC7VGIuBYH gR6Q== X-Gm-Message-State: AMCzsaUvP6TPrEtUvBU0S+HwasCDQ/8AUmvZImys5NQsseg5825w94wY N7m3KQRuskuad3o/Z4LpNURvNw== X-Google-Smtp-Source: ABhQp+TwG79dbh0JzYxq4twuoNBH4AD+pAAD3aQroF0qsvMSRTuFvEW9f5Rgh7u94zYt3euA4zsIgg== X-Received: by 10.98.223.137 with SMTP id d9mr4566731pfl.98.1509239707239; Sat, 28 Oct 2017 18:15:07 -0700 (PDT) Received: from os42.localdomain (ip68-4-115-207.oc.oc.cox.net. [68.4.115.207]) by smtp.gmail.com with ESMTPSA id 74sm24267387pft.184.2017.10.28.18.15.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 28 Oct 2017 18:15:06 -0700 (PDT) From: James Smart To: linux-scsi@vger.kernel.org Cc: James Smart , Dick Kennedy , James Smart Subject: [PATCH 4/5] lpfc: Add NVME rescan support via RSCNs Date: Sat, 28 Oct 2017 18:14:55 -0700 Message-Id: <20171029011456.12885-5-jsmart2021@gmail.com> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171029011456.12885-1-jsmart2021@gmail.com> References: <20171029011456.12885-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 This patch adds NVME rescan support via RSCNs NVME Target: Adds support for the new nvme_subsystem_change callback. The callback can be invoked by the nvmet_fc transport when it detects conditions that would like to have nvme discovery invoked again. Typically this is upon the addition of new subsystems added to the nvmet configuration (thus the transport tying the callback being invoked to port add calls). The callback routine will generate an RSCN to the fabric in order to cause RSCN events to all initiators with view of the nport. NVME Host: Upon reception of an RSCN event for an nport which supports NVME initiator and which is currently logged in and PRLI'd, the initiator will call the nvme_fc transport nvme_fc_rescan_remoteport() routine to request nvme discovery to be performed again on the port pair. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_crtn.h | 2 ++ drivers/scsi/lpfc/lpfc_els.c | 4 ++++ drivers/scsi/lpfc/lpfc_nvme.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/lpfc/lpfc_nvmet.c | 18 ++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 6657b71d5a57..86f034fefa46 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -546,6 +546,8 @@ int lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox); void lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb); /* NVME interfaces. */ +void lpfc_nvme_rescan_port(struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp); void lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp); int lpfc_nvme_register_port(struct lpfc_vport *vport, diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 936fc22dfcae..b02684113c75 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -6071,6 +6071,10 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) if (vport->phba->nvmet_support) continue; + /* Check to see if we need to NVME rescan this remoteport. */ + if (ndlp->nlp_fc4_type & NLP_FC4_NVME) + lpfc_nvme_rescan_port(vport, ndlp); + lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); lpfc_cancel_retry_delay_tmo(vport, ndlp); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 23bdb1ca106e..b372da3672eb 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2375,6 +2375,48 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) #endif } +/* lpfc_nvme_rescan_port - Check to see if we should rescan this remoteport + * + * If the ndlp represents an NVME Target, that we are logged into, + * ping the NVME FC Transport layer to initiate a device rescan + * on this remote NPort. + */ +void +lpfc_nvme_rescan_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) +{ +#if (IS_ENABLED(CONFIG_NVME_FC)) + struct lpfc_nvme_rport *rport; + struct nvme_fc_remote_port *remoteport; + + rport = ndlp->nrport; + + lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, + "6170 Rescan NPort DID x%06x type x%x state x%x rport %p\n", + ndlp->nlp_DID, ndlp->nlp_type, ndlp->nlp_state, rport); + if (!rport) + goto input_err; + remoteport = rport->remoteport; + if (!remoteport) + goto input_err; + + /* Only rescan if we are an NVME target in the MAPPED state */ + if (remoteport->port_role & FC_PORT_ROLE_NVME_TARGET && + ndlp->nlp_state == NLP_STE_MAPPED_NODE) { + nvme_fc_rescan_remoteport(remoteport); + + lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, + "6172 NVME rescanned DID x%06x " + "port_state x%x\n", + ndlp->nlp_DID, remoteport->port_state); + } +input_err: + return; +#endif + lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, + "6169 State error: lport %p, rport%p FCID x%06x\n", + vport->localport, ndlp->rport, ndlp->nlp_DID); +} + /* lpfc_nvme_unregister_port - unbind the DID and port_role from this rport. * * There is no notion of Devloss or rport recovery from the current diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 0b7c1a49e203..51888192eed7 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -866,6 +866,23 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport, lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */ } +static void +lpfc_nvmet_subsystem_change(struct nvmet_fc_target_port *tgtport) +{ + struct lpfc_nvmet_tgtport *tgtp; + struct lpfc_hba *phba; + uint32_t rc; + + tgtp = tgtport->private; + phba = tgtp->phba; + + rc = lpfc_issue_els_rscn(phba->pport, 0); + lpfc_printf_log(phba, KERN_ERR, LOG_NVME, + "6420 NVMET subsystem change: " + "Notification %s\n", + (rc) ? "Failed" : "Sent"); +} + static struct nvmet_fc_target_template lpfc_tgttemplate = { .targetport_delete = lpfc_nvmet_targetport_delete, .xmt_ls_rsp = lpfc_nvmet_xmt_ls_rsp, @@ -873,6 +890,7 @@ static struct nvmet_fc_target_template lpfc_tgttemplate = { .fcp_abort = lpfc_nvmet_xmt_fcp_abort, .fcp_req_release = lpfc_nvmet_xmt_fcp_release, .defer_rcv = lpfc_nvmet_defer_rcv, + .nvme_subsystem_change = lpfc_nvmet_subsystem_change, .max_hw_queues = 1, .max_sgl_segments = LPFC_NVMET_DEFAULT_SEGS,