All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan
@ 2019-05-13 22:43 James Smart
  2019-05-13 22:43 ` [PATCH 1/7] nvmet: add transport discovery change op James Smart
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


A transport may have a transport-specific mechanism that can signal
when discovery controller content has changed and request a host
to rescan to the discovery controller.

FC is such a transport. RSCNs may be generated by the subsystem's FC
port and sent to the initiator or fabric controller. If a fabric, the
fabric controller will broadcast the RSCN to registered hosts. A host,
upon receiving the RSCN, would validate connectivity then initiate a
discovery controller rescan.

These patches:
- Modify the nvmet core layer to call a transport callback whenever
  a port discovery change occurs.  To facilitate the callback and
  avoid new routines between core. and discovery.c the port structure
  now has a copy of the transport ops structure.
- Modify the nvmet-fc transport to support the nvmet callback, and add
  its own internal lldd api to request the lldd to generate an RSCN.
- Update nvme-fcloop test harness to support the lldd api and invoke
  the rescan on the host.
- Modify the lpfc driver to support the new interfaces:
  - Adds a new routine to transmit an RSCN to the other port (pt2pt)
    or fabric controller.  Add recognition for receipt of an RSCN.
  - Add support for the nvmet lldd api for discovery event, which
    invokes the RSCN transmit.
  - Ties into the RSCN receipt and requests the nvme_fc transport
    to rescan the remote port (discovery event will be posted).
  - Adds a sysfs routine to enable manual generation of an RSCN.

The patches were cut against the nvme-5.2 branch

Due to the dependence of the lpfc mods on the new nvme apis, the
patches are intended to be merged through the nvme tree and *not* the
scsi tree.


James Smart (7):
  nvmet: add transport discovery change op
  nvmet_fc: add transport discovery change event callback support
  nvme-fcloop: Add support for nvmet discovery_event op
  lpfc: Add support to generate RSCN events for nport
  lpfc: add nvmet discovery_event op support
  lpfc: Add support for translating an RSCN rcv into a discovery rescan
  lpfc: Add sysfs interface to post NVME RSCN

 drivers/nvme/target/core.c       |   2 +
 drivers/nvme/target/discovery.c  |   4 ++
 drivers/nvme/target/fc.c         |  11 ++++
 drivers/nvme/target/fcloop.c     |  37 ++++++++++++
 drivers/nvme/target/nvmet.h      |   2 +
 drivers/scsi/lpfc/lpfc.h         |   2 +
 drivers/scsi/lpfc/lpfc_attr.c    |  60 ++++++++++++++++++
 drivers/scsi/lpfc/lpfc_crtn.h    |   4 ++
 drivers/scsi/lpfc/lpfc_els.c     | 127 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/lpfc/lpfc_hbadisc.c |  35 +++++++++++
 drivers/scsi/lpfc/lpfc_hw.h      |   2 +
 drivers/scsi/lpfc/lpfc_nvme.c    |  44 ++++++++++++++
 drivers/scsi/lpfc/lpfc_nvmet.c   |  17 ++++++
 drivers/scsi/lpfc/lpfc_sli.c     |   1 +
 include/linux/nvme-fc-driver.h   |   6 ++
 15 files changed, 354 insertions(+)

-- 
2.13.7

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/7] nvmet: add transport discovery change op
  2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
@ 2019-05-13 22:43 ` James Smart
  2019-05-14 10:12   ` Hannes Reinecke
  2019-05-13 22:43 ` [PATCH 2/7] nvmet_fc: add transport discovery change event callback support James Smart
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


Some transports, such as FC-NVME, support discovery controller change
events without the use of a persistent discovery controller. FC receives
events via RSCN from the FC Fabric Controller or subsystem FC port.

This patch adds a nvmet transport op that is called whenever a
discovery change event occurs in the nvmet layer.

To facilitate the callback without adding another layer to cross into
core.c to reference the transport ops, the port structure snapshots
the transport ops when the port is enabled and clears them when disabled.

Signed-off-by: James Smart <jsmart2021 at gmail.com>
---
 drivers/nvme/target/core.c      | 2 ++
 drivers/nvme/target/discovery.c | 4 ++++
 drivers/nvme/target/nvmet.h     | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 7734a6acff85..43e8c4adc1f4 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -311,6 +311,7 @@ int nvmet_enable_port(struct nvmet_port *port)
 		port->inline_data_size = 0;
 
 	port->enabled = true;
+	port->tr_ops = ops;
 	return 0;
 }
 
@@ -321,6 +322,7 @@ void nvmet_disable_port(struct nvmet_port *port)
 	lockdep_assert_held(&nvmet_config_sem);
 
 	port->enabled = false;
+	port->tr_ops = NULL;
 
 	ops = nvmet_transports[port->disc_addr.trtype];
 	ops->remove_port(port);
diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
index 5baf269f3f8a..8efca26b4776 100644
--- a/drivers/nvme/target/discovery.c
+++ b/drivers/nvme/target/discovery.c
@@ -41,6 +41,10 @@ void nvmet_port_disc_changed(struct nvmet_port *port,
 		__nvmet_disc_changed(port, ctrl);
 	}
 	mutex_unlock(&nvmet_disc_subsys->lock);
+
+	/* If transport can signal change, notify transport */
+	if (port->tr_ops && port->tr_ops->discovery_chg)
+		port->tr_ops->discovery_chg(port);
 }
 
 static void __nvmet_subsys_disc_changed(struct nvmet_port *port,
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index c25d88fc9dec..dc270944bb25 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -140,6 +140,7 @@ struct nvmet_port {
 	void				*priv;
 	bool				enabled;
 	int				inline_data_size;
+	const struct nvmet_fabrics_ops	*tr_ops;
 };
 
 static inline struct nvmet_port *to_nvmet_port(struct config_item *item)
@@ -277,6 +278,7 @@ struct nvmet_fabrics_ops {
 	void (*disc_traddr)(struct nvmet_req *req,
 			struct nvmet_port *port, char *traddr);
 	u16 (*install_queue)(struct nvmet_sq *nvme_sq);
+	void (*discovery_chg)(struct nvmet_port *port);
 };
 
 #define NVMET_MAX_INLINE_BIOVEC	8
-- 
2.13.7

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/7] nvmet_fc: add transport discovery change event callback support
  2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
  2019-05-13 22:43 ` [PATCH 1/7] nvmet: add transport discovery change op James Smart
@ 2019-05-13 22:43 ` James Smart
  2019-05-14 10:17   ` Hannes Reinecke
  2019-05-13 22:43 ` [PATCH 3/7] nvme-fcloop: Add support for nvmet discovery_event op James Smart
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


This patch adds support for the nvmet discovery_change transport op.
In turn, the transport adds it's own LLDD api callback discovery_event
op to request the LLDD to generate an RSCN for the discovery change.

Signed-off-by: James Smart <jsmart2021 at gmail.com>
---
 drivers/nvme/target/fc.c       | 11 +++++++++++
 include/linux/nvme-fc-driver.h |  6 ++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index 508661af0f50..1f252c9a953a 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -2549,6 +2549,16 @@ nvmet_fc_remove_port(struct nvmet_port *port)
 	kfree(pe);
 }
 
+static void
+nvmet_fc_discovery_chg(struct nvmet_port *port)
+{
+	struct nvmet_fc_port_entry *pe = port->priv;
+	struct nvmet_fc_tgtport *tgtport = pe->tgtport;
+
+	if (tgtport && tgtport->ops->discovery_event)
+		tgtport->ops->discovery_event(&tgtport->fc_target_port);
+}
+
 static const struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops = {
 	.owner			= THIS_MODULE,
 	.type			= NVMF_TRTYPE_FC,
@@ -2557,6 +2567,7 @@ static const struct nvmet_fabrics_ops nvmet_fc_tgt_fcp_ops = {
 	.remove_port		= nvmet_fc_remove_port,
 	.queue_response		= nvmet_fc_fcp_nvme_cmd_done,
 	.delete_ctrl		= nvmet_fc_delete_ctrl,
+	.discovery_chg		= nvmet_fc_discovery_chg,
 };
 
 static int __init nvmet_fc_init_module(void)
diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h
index 2bb349035431..5bbcb7afef39 100644
--- a/include/linux/nvme-fc-driver.h
+++ b/include/linux/nvme-fc-driver.h
@@ -797,6 +797,11 @@ struct nvmet_fc_target_port {
  *       nvmefc_tgt_fcp_req.
  *       Entrypoint is Optional.
  *
+ * @discovery_event:  Called by the transport to generate an RSCN
+ *       change notifications to NVME initiators. The RSCN notifications
+ *       should cause the initiator to rescan the discovery controller
+ *       on the targetport.
+ *
  * @max_hw_queues:  indicates the maximum number of hw queues the LLDD
  *       supports for cpu affinitization.
  *       Value is Mandatory. Must be at least 1.
@@ -838,6 +843,7 @@ struct nvmet_fc_target_template {
 				struct nvmefc_tgt_fcp_req *fcpreq);
 	void (*defer_rcv)(struct nvmet_fc_target_port *tgtport,
 				struct nvmefc_tgt_fcp_req *fcpreq);
+	void (*discovery_event)(struct nvmet_fc_target_port *tgtport);
 
 	u32	max_hw_queues;
 	u16	max_sgl_segments;
-- 
2.13.7

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/7] nvme-fcloop: Add support for nvmet discovery_event op
  2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
  2019-05-13 22:43 ` [PATCH 1/7] nvmet: add transport discovery change op James Smart
  2019-05-13 22:43 ` [PATCH 2/7] nvmet_fc: add transport discovery change event callback support James Smart
@ 2019-05-13 22:43 ` James Smart
  2019-05-14 10:17   ` Hannes Reinecke
  2019-05-13 22:43 ` [PATCH 4/7] lpfc: Add support to generate RSCN events for nport James Smart
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


Update fcloop to support the discovery_event operation and
invoke a nvme rescan. In a real fc adapter, this would generate an
RSCN, which the host would receive and convert into a nvme rescan
on the remote port specified in the rscn payload.

Signed-off-by: James Smart <jsmart2021 at gmail.com>
---
 drivers/nvme/target/fcloop.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
index 381b5a90c48b..6ddcd090ec07 100644
--- a/drivers/nvme/target/fcloop.c
+++ b/drivers/nvme/target/fcloop.c
@@ -231,6 +231,11 @@ struct fcloop_lsreq {
 	int				status;
 };
 
+struct fcloop_rscn {
+	struct fcloop_tport		*tport;
+	struct work_struct		work;
+};
+
 enum {
 	INI_IO_START		= 0,
 	INI_IO_ACTIVE		= 1,
@@ -348,6 +353,37 @@ fcloop_xmt_ls_rsp(struct nvmet_fc_target_port *tport,
 	return 0;
 }
 
+/*
+ * Simulate reception of RSCN and converting it to a initiator transport
+ * call to rescan a remote port.
+ */
+static void
+fcloop_tgt_rscn_work(struct work_struct *work)
+{
+	struct fcloop_rscn *tgt_rscn =
+		container_of(work, struct fcloop_rscn, work);
+	struct fcloop_tport *tport = tgt_rscn->tport;
+
+	if (tport->remoteport)
+		nvme_fc_rescan_remoteport(tport->remoteport);
+	kfree(tgt_rscn);
+}
+
+void
+fcloop_tgt_discovery_evt(struct nvmet_fc_target_port *tgtport)
+{
+	struct fcloop_rscn *tgt_rscn;
+
+	tgt_rscn = kzalloc(sizeof(*tgt_rscn), GFP_KERNEL);
+	if (!tgt_rscn)
+		return;
+
+	tgt_rscn->tport = tgtport->private;
+	INIT_WORK(&tgt_rscn->work, fcloop_tgt_rscn_work);
+
+	schedule_work(&tgt_rscn->work);
+}
+
 static void
 fcloop_tfcp_req_free(struct kref *ref)
 {
@@ -839,6 +875,7 @@ static struct nvmet_fc_target_template tgttemplate = {
 	.fcp_op			= fcloop_fcp_op,
 	.fcp_abort		= fcloop_tgt_fcp_abort,
 	.fcp_req_release	= fcloop_fcp_req_release,
+	.discovery_event	= fcloop_tgt_discovery_evt,
 	.max_hw_queues		= FCLOOP_HW_QUEUES,
 	.max_sgl_segments	= FCLOOP_SGL_SEGS,
 	.max_dif_sgl_segments	= FCLOOP_SGL_SEGS,
-- 
2.13.7

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] lpfc: Add support to generate RSCN events for nport
  2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
                   ` (2 preceding siblings ...)
  2019-05-13 22:43 ` [PATCH 3/7] nvme-fcloop: Add support for nvmet discovery_event op James Smart
@ 2019-05-13 22:43 ` James Smart
  2019-05-14 10:20   ` Hannes Reinecke
  2019-05-13 22:43 ` [PATCH 5/7] lpfc: add nvmet discovery_event op support James Smart
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


This patch adds general RSCN support:
- The ability to transmit an RSCN to the port on the other end of
  the link (regular port if pt2pt, or fabric controller if fabric).
- And general recognition of an RSCN ELS when an ELS is received.

Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
---
 drivers/scsi/lpfc/lpfc.h         |   1 +
 drivers/scsi/lpfc/lpfc_crtn.h    |   2 +
 drivers/scsi/lpfc/lpfc_els.c     | 122 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/lpfc/lpfc_hbadisc.c |  35 +++++++++++
 drivers/scsi/lpfc/lpfc_hw.h      |   2 +
 drivers/scsi/lpfc/lpfc_sli.c     |   1 +
 6 files changed, 163 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 41d849f283f6..9246e0212a86 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -274,6 +274,7 @@ struct lpfc_stats {
 	uint32_t elsXmitADISC;
 	uint32_t elsXmitLOGO;
 	uint32_t elsXmitSCR;
+	uint32_t elsXmitRSCN;
 	uint32_t elsXmitRNID;
 	uint32_t elsXmitFARP;
 	uint32_t elsXmitFARPR;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index e0b14d791b8c..4b8eb9107b85 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -141,6 +141,7 @@ int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
 int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t);
 int lpfc_issue_els_npiv_logo(struct lpfc_vport *, struct lpfc_nodelist *);
 int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t);
+int lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry);
 int lpfc_issue_fabric_reglogin(struct lpfc_vport *);
 int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
 int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
@@ -355,6 +356,7 @@ void lpfc_mbox_timeout_handler(struct lpfc_hba *);
 struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
 struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
 					 struct lpfc_name *);
+struct lpfc_nodelist *lpfc_findnode_mapped(struct lpfc_vport *vport);
 
 int lpfc_sli_issue_mbox_wait(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
 
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index fc077cb87900..c9a40e05edcc 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -30,6 +30,8 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
+#include <uapi/scsi/fc/fc_fs.h>
+#include <uapi/scsi/fc/fc_els.h>
 
 #include "lpfc_hw4.h"
 #include "lpfc_hw.h"
@@ -3082,6 +3084,116 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
 }
 
 /**
+ * lpfc_issue_els_rscn - Issue an RSCN to the Fabric Controller (Fabric)
+ *   or the other nport (pt2pt).
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues a RSCN to the Fabric Controller (DID 0xFFFFFD)
+ *  when connected to a fabric, or to the remote port when connected
+ *  in point-to-point mode. When sent to the Fabric Controller, it will
+ *  replay the RSCN to registered recipients.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the RSCN ELS command.
+ *
+ * Return code
+ *   0 - Successfully issued RSCN command
+ *   1 - Failed to issue RSCN command
+ **/
+int
+lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry)
+{
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_iocbq *elsiocb;
+	struct lpfc_nodelist *ndlp;
+	struct {
+		struct fc_els_rscn rscn;
+		struct fc_els_rscn_page portid;
+	} *event;
+	uint32_t nportid;
+	uint16_t cmdsize = sizeof(*event);
+
+	/* Not supported for private loop */
+	if (phba->fc_topology == LPFC_TOPOLOGY_LOOP &&
+	    !(vport->fc_flag & FC_PUBLIC_LOOP))
+		return 1;
+
+	if (vport->fc_flag & FC_PT2PT) {
+		/* find any mapped nport - that would be the other nport */
+		ndlp = lpfc_findnode_mapped(vport);
+		if (!ndlp)
+			return 1;
+	} else {
+		nportid = FC_FID_FCTRL;
+		/* find the fabric controller node */
+		ndlp = lpfc_findnode_did(vport, nportid);
+		if (!ndlp) {
+			/* if one didn't exist, make one */
+			ndlp = lpfc_nlp_init(vport, nportid);
+			if (!ndlp)
+				return 1;
+			lpfc_enqueue_node(vport, ndlp);
+		} else if (!NLP_CHK_NODE_ACT(ndlp)) {
+			ndlp = lpfc_enable_node(vport, ndlp,
+						NLP_STE_UNUSED_NODE);
+			if (!ndlp)
+				return 1;
+		}
+	}
+
+	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
+				     ndlp->nlp_DID, ELS_CMD_RSCN_XMT);
+
+	if (!elsiocb) {
+		/* This will trigger the release of the node just
+		 * allocated
+		 */
+		lpfc_nlp_put(ndlp);
+		return 1;
+	}
+
+	event = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
+
+	event->rscn.rscn_cmd = ELS_RSCN;
+	event->rscn.rscn_page_len = sizeof(struct fc_els_rscn_page);
+	event->rscn.rscn_plen = cpu_to_be16(cmdsize);
+
+	nportid = vport->fc_myDID;
+	/* appears that page flags must be 0 for fabric to broadcast RSCN */
+	event->portid.rscn_page_flags = 0;
+	event->portid.rscn_fid[0] = (nportid & 0x00FF0000) >> 16;
+	event->portid.rscn_fid[1] = (nportid & 0x0000FF00) >> 8;
+	event->portid.rscn_fid[2] = nportid & 0x000000FF;
+
+	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
+			      "Issue RSCN:       did:x%x",
+			      ndlp->nlp_DID, 0, 0);
+
+	phba->fc_stat.elsXmitRSCN++;
+	elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
+	if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
+	    IOCB_ERROR) {
+		/* The additional lpfc_nlp_put will cause the following
+		 * lpfc_els_free_iocb routine to trigger the rlease of
+		 * the node.
+		 */
+		lpfc_nlp_put(ndlp);
+		lpfc_els_free_iocb(phba, elsiocb);
+		return 1;
+	}
+	/* This will cause the callback-function lpfc_cmpl_els_cmd to
+	 * trigger the release of node.
+	 */
+	if (!(vport->fc_flag & FC_PT2PT))
+		lpfc_nlp_put(ndlp);
+
+	return 0;
+}
+
+/**
  * lpfc_issue_els_farpr - Issue a farp to an node on a vport
  * @vport: pointer to a host virtual N_Port data structure.
  * @nportid: N_Port identifier to the remote node.
@@ -6321,6 +6433,16 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 		fc_host_post_event(shost, fc_get_event_number(),
 			FCH_EVT_RSCN, lp[i]);
 
+	/* Check if RSCN is coming from a direct-connected remote NPort */
+	if (vport->fc_flag & FC_PT2PT) {
+		/* If so, just ACC it, no other action needed for now */
+		lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+				 "2024 pt2pt RSCN %08x Data: x%x x%x\n",
+				 *lp, vport->fc_flag, payload_len);
+		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+		return 0;
+	}
+
 	/* If we are about to begin discovery, just ACC the RSCN.
 	 * Discovery processing will satisfy it.
 	 */
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index aa4961a2caf8..9b016666601f 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -5261,6 +5261,41 @@ lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
 }
 
 struct lpfc_nodelist *
+lpfc_findnode_mapped(struct lpfc_vport *vport)
+{
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_nodelist *ndlp;
+	uint32_t data1;
+	unsigned long iflags;
+
+	spin_lock_irqsave(shost->host_lock, iflags);
+
+	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+		if (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE ||
+		    ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
+			data1 = (((uint32_t)ndlp->nlp_state << 24) |
+				 ((uint32_t)ndlp->nlp_xri << 16) |
+				 ((uint32_t)ndlp->nlp_type << 8) |
+				 ((uint32_t)ndlp->nlp_rpi & 0xff));
+			spin_unlock_irqrestore(shost->host_lock, iflags);
+			lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+					 "2025 FIND node DID "
+					 "Data: x%p x%x x%x x%x %p\n",
+					 ndlp, ndlp->nlp_DID,
+					 ndlp->nlp_flag, data1,
+					 ndlp->active_rrqs_xri_bitmap);
+			return ndlp;
+		}
+	}
+	spin_unlock_irqrestore(shost->host_lock, iflags);
+
+	/* FIND node did <did> NOT FOUND */
+	lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+			 "2026 FIND mapped did NOT FOUND.\n");
+	return NULL;
+}
+
+struct lpfc_nodelist *
 lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
 {
 	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index ec1227018913..5e5b3318042e 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -599,6 +599,7 @@ struct fc_vft_header {
 #define ELS_CMD_RPL       0x57000000
 #define ELS_CMD_FAN       0x60000000
 #define ELS_CMD_RSCN      0x61040000
+#define ELS_CMD_RSCN_XMT  0x61040008
 #define ELS_CMD_SCR       0x62000000
 #define ELS_CMD_RNID      0x78000000
 #define ELS_CMD_LIRR      0x7A000000
@@ -639,6 +640,7 @@ struct fc_vft_header {
 #define ELS_CMD_RPL       0x57
 #define ELS_CMD_FAN       0x60
 #define ELS_CMD_RSCN      0x0461
+#define ELS_CMD_RSCN_XMT  0x08000461
 #define ELS_CMD_SCR       0x62
 #define ELS_CMD_RNID      0x78
 #define ELS_CMD_LIRR      0x7A
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 57b4a463b589..cbe7a0f36f4b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -9373,6 +9373,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) {
 			if (pcmd && (*pcmd == ELS_CMD_FLOGI ||
 				*pcmd == ELS_CMD_SCR ||
+				*pcmd == ELS_CMD_RSCN_XMT ||
 				*pcmd == ELS_CMD_FDISC ||
 				*pcmd == ELS_CMD_LOGO ||
 				*pcmd == ELS_CMD_PLOGI)) {
-- 
2.13.7

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/7] lpfc: add nvmet discovery_event op support
  2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
                   ` (3 preceding siblings ...)
  2019-05-13 22:43 ` [PATCH 4/7] lpfc: Add support to generate RSCN events for nport James Smart
@ 2019-05-13 22:43 ` James Smart
  2019-05-14 10:20   ` Hannes Reinecke
  2019-05-13 22:43 ` [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan James Smart
  2019-05-13 22:43 ` [PATCH 7/7] lpfc: Add sysfs interface to post NVME RSCN James Smart
  6 siblings, 1 reply; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


This patch adds support for the nvmet discovery op. When the callback
routine is called, the driver will call the routine to generate an RSCN
to the port on the other end of the link.

Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
---
 drivers/scsi/lpfc/lpfc_nvmet.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index 361e2b103648..1eb02a0b8db6 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -1141,6 +1141,22 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
 	spin_unlock_irqrestore(&ctxp->ctxlock, iflag);
 }
 
+static void
+lpfc_nvmet_discovery_event(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,
@@ -1148,6 +1164,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,
+	.discovery_event = lpfc_nvmet_discovery_event,
 
 	.max_hw_queues  = 1,
 	.max_sgl_segments = LPFC_NVMET_DEFAULT_SEGS,
-- 
2.13.7

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan
  2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
                   ` (4 preceding siblings ...)
  2019-05-13 22:43 ` [PATCH 5/7] lpfc: add nvmet discovery_event op support James Smart
@ 2019-05-13 22:43 ` James Smart
  2019-05-14 10:22   ` Hannes Reinecke
  2019-05-14 19:04   ` Arun Easi
  2019-05-13 22:43 ` [PATCH 7/7] lpfc: Add sysfs interface to post NVME RSCN James Smart
  6 siblings, 2 replies; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


This patch updates RSCN receive processing to check for the remote
port being an NVME port, and if so, invoke the nvme_fc callback to
rescan the remote port.  The rescan will generate a discovery udev
event.

Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
---
 drivers/scsi/lpfc/lpfc_crtn.h |  2 ++
 drivers/scsi/lpfc/lpfc_els.c  |  5 +++++
 drivers/scsi/lpfc/lpfc_nvme.c | 44 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 4b8eb9107b85..866374801140 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -557,6 +557,8 @@ void lpfc_ras_stop_fwlog(struct lpfc_hba *phba);
 int lpfc_check_fwlog_support(struct lpfc_hba *phba);
 
 /* 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 c9a40e05edcc..c8b305c1aafb 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -6329,6 +6329,8 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
 			continue;
 		}
 
+		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);
@@ -6440,6 +6442,9 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 				 "2024 pt2pt RSCN %08x Data: x%x x%x\n",
 				 *lp, vport->fc_flag, payload_len);
 		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
+
+		if (ndlp->nlp_fc4_type & NLP_FC4_NVME)
+			lpfc_nvme_rescan_port(vport, ndlp);
 		return 0;
 	}
 
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 1aa00d2c3f74..6f179de44fc7 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -2399,6 +2399,50 @@ 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);
+	}
+	return;
+input_err:
+	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);
+#endif
+}
+
 /* 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
-- 
2.13.7

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] lpfc: Add sysfs interface to post NVME RSCN
  2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
                   ` (5 preceding siblings ...)
  2019-05-13 22:43 ` [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan James Smart
@ 2019-05-13 22:43 ` James Smart
  2019-05-14 10:22   ` Hannes Reinecke
  6 siblings, 1 reply; 16+ messages in thread
From: James Smart @ 2019-05-13 22:43 UTC (permalink / raw)


To support scenarios which aren't bound to nvmetcli add port scenarios,
which is currently where the nvmet_fc transport invokes the discovery
event callbacks, a syfs attribute is added to lpfc which can be written
to cause an RSCN to be generated for the nport.

Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <jsmart2021 at gmail.com>
---
 drivers/scsi/lpfc/lpfc.h      |  1 +
 drivers/scsi/lpfc/lpfc_attr.c | 60 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 9246e0212a86..5ef0efb830d2 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -820,6 +820,7 @@ struct lpfc_hba {
 	uint32_t cfg_use_msi;
 	uint32_t cfg_auto_imax;
 	uint32_t cfg_fcp_imax;
+	uint32_t cfg_force_rscn;
 	uint32_t cfg_cq_poll_threshold;
 	uint32_t cfg_cq_max_proc_limit;
 	uint32_t cfg_fcp_cpu_map;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index ce3e541434dc..8b09e82ddfcf 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -4912,6 +4912,64 @@ static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
 		   lpfc_request_firmware_upgrade_store);
 
 /**
+ * lpfc_force_rscn_store
+ *
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: unused string
+ * @count: unused variable.
+ *
+ * Description:
+ * Force the switch to send a RSCN to all other NPorts in our zone
+ * If we are direct connect pt2pt, build the RSCN command ourself
+ * and send to the other NPort. Not supported for private loop.
+ *
+ * Returns:
+ * 0      - on success
+ * -EIO   - if command is not sent
+ **/
+static ssize_t
+lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
+		      const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
+	int i;
+
+	i = lpfc_issue_els_rscn(vport, 0);
+	if (i)
+		return -EIO;
+	return strlen(buf);
+}
+
+/*
+ * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
+ * connected to  the HBA.
+ *
+ * Value range is any ascii value
+ */
+static int lpfc_force_rscn;
+module_param(lpfc_force_rscn, int, 0644);
+MODULE_PARM_DESC(lpfc_force_rscn,
+		 "Force an RSCN to be sent to all remote NPorts");
+lpfc_param_show(force_rscn)
+
+/**
+ * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
+ * @phba: lpfc_hba pointer.
+ * @val: unused value.
+ *
+ * Returns:
+ * zero if val saved.
+ **/
+static int
+lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
+{
+	return 0;
+}
+static DEVICE_ATTR_RW(lpfc_force_rscn);
+
+/**
  * lpfc_fcp_imax_store
  *
  * @dev: class device that is converted into a Scsi_host.
@@ -5911,6 +5969,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
 	&dev_attr_lpfc_nvme_oas,
 	&dev_attr_lpfc_nvme_embed_cmd,
 	&dev_attr_lpfc_fcp_imax,
+	&dev_attr_lpfc_force_rscn,
 	&dev_attr_lpfc_cq_poll_threshold,
 	&dev_attr_lpfc_cq_max_proc_limit,
 	&dev_attr_lpfc_fcp_cpu_map,
@@ -6958,6 +7017,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 	lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
 	lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
 	lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
+	lpfc_force_rscn_init(phba, lpfc_force_rscn);
 	lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
 	lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
 	lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
-- 
2.13.7

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 1/7] nvmet: add transport discovery change op
  2019-05-13 22:43 ` [PATCH 1/7] nvmet: add transport discovery change op James Smart
@ 2019-05-14 10:12   ` Hannes Reinecke
  0 siblings, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2019-05-14 10:12 UTC (permalink / raw)


On 5/14/19 12:43 AM, James Smart wrote:
> Some transports, such as FC-NVME, support discovery controller change
> events without the use of a persistent discovery controller. FC receives
> events via RSCN from the FC Fabric Controller or subsystem FC port.
> 
> This patch adds a nvmet transport op that is called whenever a
> discovery change event occurs in the nvmet layer.
> 
> To facilitate the callback without adding another layer to cross into
> core.c to reference the transport ops, the port structure snapshots
> the transport ops when the port is enabled and clears them when disabled.
> 
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>   drivers/nvme/target/core.c      | 2 ++
>   drivers/nvme/target/discovery.c | 4 ++++
>   drivers/nvme/target/nvmet.h     | 2 ++
>   3 files changed, 8 insertions(+)
> 
I like the idea, and something like this is in fact required when 
restarting nvmetcli.

Reviewed-by: Hannes Reinecke <hare at suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG N?rnberg)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 2/7] nvmet_fc: add transport discovery change event callback support
  2019-05-13 22:43 ` [PATCH 2/7] nvmet_fc: add transport discovery change event callback support James Smart
@ 2019-05-14 10:17   ` Hannes Reinecke
  0 siblings, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2019-05-14 10:17 UTC (permalink / raw)


On 5/14/19 12:43 AM, James Smart wrote:
> This patch adds support for the nvmet discovery_change transport op.
> In turn, the transport adds it's own LLDD api callback discovery_event
> op to request the LLDD to generate an RSCN for the discovery change.
> 
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>   drivers/nvme/target/fc.c       | 11 +++++++++++
>   include/linux/nvme-fc-driver.h |  6 ++++++
>   2 files changed, 17 insertions(+)
> 
Reviewed-by: Hannes Reinecke <hare at suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG N?rnberg)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 3/7] nvme-fcloop: Add support for nvmet discovery_event op
  2019-05-13 22:43 ` [PATCH 3/7] nvme-fcloop: Add support for nvmet discovery_event op James Smart
@ 2019-05-14 10:17   ` Hannes Reinecke
  0 siblings, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2019-05-14 10:17 UTC (permalink / raw)


On 5/14/19 12:43 AM, James Smart wrote:
> Update fcloop to support the discovery_event operation and
> invoke a nvme rescan. In a real fc adapter, this would generate an
> RSCN, which the host would receive and convert into a nvme rescan
> on the remote port specified in the rscn payload.
> 
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>   drivers/nvme/target/fcloop.c | 37 +++++++++++++++++++++++++++++++++++++
>   1 file changed, 37 insertions(+)
> 
Reviewed-by: Hannes Reinecke <hare at suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG N?rnberg)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 4/7] lpfc: Add support to generate RSCN events for nport
  2019-05-13 22:43 ` [PATCH 4/7] lpfc: Add support to generate RSCN events for nport James Smart
@ 2019-05-14 10:20   ` Hannes Reinecke
  0 siblings, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2019-05-14 10:20 UTC (permalink / raw)


On 5/14/19 12:43 AM, James Smart wrote:
> This patch adds general RSCN support:
> - The ability to transmit an RSCN to the port on the other end of
>    the link (regular port if pt2pt, or fabric controller if fabric).
> - And general recognition of an RSCN ELS when an ELS is received.
> 
> Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>   drivers/scsi/lpfc/lpfc.h         |   1 +
>   drivers/scsi/lpfc/lpfc_crtn.h    |   2 +
>   drivers/scsi/lpfc/lpfc_els.c     | 122 +++++++++++++++++++++++++++++++++++++++
>   drivers/scsi/lpfc/lpfc_hbadisc.c |  35 +++++++++++
>   drivers/scsi/lpfc/lpfc_hw.h      |   2 +
>   drivers/scsi/lpfc/lpfc_sli.c     |   1 +
>   6 files changed, 163 insertions(+)
> 

Reviewed-by: Hannes Reinecke <hare at suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG N?rnberg)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 5/7] lpfc: add nvmet discovery_event op support
  2019-05-13 22:43 ` [PATCH 5/7] lpfc: add nvmet discovery_event op support James Smart
@ 2019-05-14 10:20   ` Hannes Reinecke
  0 siblings, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2019-05-14 10:20 UTC (permalink / raw)


On 5/14/19 12:43 AM, James Smart wrote:
> This patch adds support for the nvmet discovery op. When the callback
> routine is called, the driver will call the routine to generate an RSCN
> to the port on the other end of the link.
> 
> Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>   drivers/scsi/lpfc/lpfc_nvmet.c | 17 +++++++++++++++++
>   1 file changed, 17 insertions(+)
> 
Reviewed-by: Hannes Reinecke <hare at suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG N?rnberg)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan
  2019-05-13 22:43 ` [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan James Smart
@ 2019-05-14 10:22   ` Hannes Reinecke
  2019-05-14 19:04   ` Arun Easi
  1 sibling, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2019-05-14 10:22 UTC (permalink / raw)


On 5/14/19 12:43 AM, James Smart wrote:
> This patch updates RSCN receive processing to check for the remote
> port being an NVME port, and if so, invoke the nvme_fc callback to
> rescan the remote port.  The rescan will generate a discovery udev
> event.
> 
> Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>   drivers/scsi/lpfc/lpfc_crtn.h |  2 ++
>   drivers/scsi/lpfc/lpfc_els.c  |  5 +++++
>   drivers/scsi/lpfc/lpfc_nvme.c | 44 +++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 51 insertions(+)
> 
Reviewed-by: Hannes Reinecke <hare at suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG N?rnberg)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7] lpfc: Add sysfs interface to post NVME RSCN
  2019-05-13 22:43 ` [PATCH 7/7] lpfc: Add sysfs interface to post NVME RSCN James Smart
@ 2019-05-14 10:22   ` Hannes Reinecke
  0 siblings, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2019-05-14 10:22 UTC (permalink / raw)


On 5/14/19 12:43 AM, James Smart wrote:
> To support scenarios which aren't bound to nvmetcli add port scenarios,
> which is currently where the nvmet_fc transport invokes the discovery
> event callbacks, a syfs attribute is added to lpfc which can be written
> to cause an RSCN to be generated for the nport.
> 
> Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>   drivers/scsi/lpfc/lpfc.h      |  1 +
>   drivers/scsi/lpfc/lpfc_attr.c | 60 +++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 61 insertions(+)
> 
Reviewed-by: Hannes Reinecke <hare at suse.com>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare at suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG N?rnberg)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan
  2019-05-13 22:43 ` [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan James Smart
  2019-05-14 10:22   ` Hannes Reinecke
@ 2019-05-14 19:04   ` Arun Easi
  1 sibling, 0 replies; 16+ messages in thread
From: Arun Easi @ 2019-05-14 19:04 UTC (permalink / raw)


On Mon, 13 May 2019, 3:43pm, James Smart wrote:

> This patch updates RSCN receive processing to check for the remote
> port being an NVME port, and if so, invoke the nvme_fc callback to
> rescan the remote port.  The rescan will generate a discovery udev
> event.
> 
> Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
> Signed-off-by: James Smart <jsmart2021 at gmail.com>
> ---
>  drivers/scsi/lpfc/lpfc_crtn.h |  2 ++
>  drivers/scsi/lpfc/lpfc_els.c  |  5 +++++
>  drivers/scsi/lpfc/lpfc_nvme.c | 44 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 51 insertions(+)
> 
> diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
> index 4b8eb9107b85..866374801140 100644
> --- a/drivers/scsi/lpfc/lpfc_crtn.h
> +++ b/drivers/scsi/lpfc/lpfc_crtn.h
> @@ -557,6 +557,8 @@ void lpfc_ras_stop_fwlog(struct lpfc_hba *phba);
>  int lpfc_check_fwlog_support(struct lpfc_hba *phba);
>  
>  /* 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 c9a40e05edcc..c8b305c1aafb 100644
> --- a/drivers/scsi/lpfc/lpfc_els.c
> +++ b/drivers/scsi/lpfc/lpfc_els.c
> @@ -6329,6 +6329,8 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
>  			continue;
>  		}
>  
> +		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);
> @@ -6440,6 +6442,9 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
>  				 "2024 pt2pt RSCN %08x Data: x%x x%x\n",
>  				 *lp, vport->fc_flag, payload_len);
>  		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
> +
> +		if (ndlp->nlp_fc4_type & NLP_FC4_NVME)
> +			lpfc_nvme_rescan_port(vport, ndlp);
>  		return 0;
>  	}
>  
> diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
> index 1aa00d2c3f74..6f179de44fc7 100644
> --- a/drivers/scsi/lpfc/lpfc_nvme.c
> +++ b/drivers/scsi/lpfc/lpfc_nvme.c
> @@ -2399,6 +2399,50 @@ 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 &&

Should not the check above be for a NVME_DISCOVERY role?

Regards,
-arun

> +	    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);
> +	}
> +	return;
> +input_err:
> +	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);
> +#endif
> +}
> +
>  /* 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
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2019-05-14 19:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-13 22:43 [PATCH 0/7] nvmet/nvmet_fc: add events for discovery controller rescan James Smart
2019-05-13 22:43 ` [PATCH 1/7] nvmet: add transport discovery change op James Smart
2019-05-14 10:12   ` Hannes Reinecke
2019-05-13 22:43 ` [PATCH 2/7] nvmet_fc: add transport discovery change event callback support James Smart
2019-05-14 10:17   ` Hannes Reinecke
2019-05-13 22:43 ` [PATCH 3/7] nvme-fcloop: Add support for nvmet discovery_event op James Smart
2019-05-14 10:17   ` Hannes Reinecke
2019-05-13 22:43 ` [PATCH 4/7] lpfc: Add support to generate RSCN events for nport James Smart
2019-05-14 10:20   ` Hannes Reinecke
2019-05-13 22:43 ` [PATCH 5/7] lpfc: add nvmet discovery_event op support James Smart
2019-05-14 10:20   ` Hannes Reinecke
2019-05-13 22:43 ` [PATCH 6/7] lpfc: Add support for translating an RSCN rcv into a discovery rescan James Smart
2019-05-14 10:22   ` Hannes Reinecke
2019-05-14 19:04   ` Arun Easi
2019-05-13 22:43 ` [PATCH 7/7] lpfc: Add sysfs interface to post NVME RSCN James Smart
2019-05-14 10:22   ` Hannes Reinecke

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.