Fix implicit logo and RSCN handling for NVMET
NVMET didn't have any RSCN handling at all and would not execute implicit LOGO when receiving a PLOGI from an rport that NVMET had in state UNMAPPED. Clean up the logic in lpfc_nlp_state_cleanup for initiators (FCP and NVME). NVMET should not respond to RSCN including allocating new ndlps so this code was conditionalized when nvmet_support is true. The check for NLP_RCV_PLOGI in lpfc_setup_disc_node was moved below the check for nvmet_support to allow the NVMET to recover initiator nodes correctly. The implicit logo was introduced with lpfc_rcv_plogi when NVMET gets a PLOGI on an ndlp in UNMAPPED state. The RSCN handling was modified to not respond to an RSCN in NVMET. Instead NVMET sends a GID_FT and determines if an NVMEP_INITIATOR it has is UNMAPPED but no longer in the zone membership. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
This commit is contained in:

committed by
Christoph Hellwig

parent
aeb3c8170b
commit
1c5b12f763
@@ -537,19 +537,53 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lpfc_ns_rsp_audit_did(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
|
||||
/*
|
||||
* To conserve rpi's, filter out addresses for other
|
||||
* vports on the same physical HBAs.
|
||||
*/
|
||||
if (Did != vport->fc_myDID &&
|
||||
(!lpfc_find_vport_by_did(phba, Did) ||
|
||||
vport->cfg_peer_port_login)) {
|
||||
if (!phba->nvmet_support) {
|
||||
/* FCPI/NVMEI path. Process Did */
|
||||
lpfc_prep_node_fc4type(vport, Did, fc4_type);
|
||||
return;
|
||||
}
|
||||
/* NVMET path. NVMET only cares about NVMEI nodes. */
|
||||
list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
|
||||
if (ndlp->nlp_type != NLP_NVME_INITIATOR ||
|
||||
ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)
|
||||
continue;
|
||||
spin_lock_irq(shost->host_lock);
|
||||
if (ndlp->nlp_DID == Did)
|
||||
ndlp->nlp_flag &= ~NLP_NVMET_RECOV;
|
||||
else
|
||||
ndlp->nlp_flag |= NLP_NVMET_RECOV;
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type,
|
||||
uint32_t Size)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct lpfc_sli_ct_request *Response =
|
||||
(struct lpfc_sli_ct_request *) mp->virt;
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
struct lpfc_dmabuf *mlast, *next_mp;
|
||||
uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
|
||||
uint32_t Did, CTentry;
|
||||
int Cnt;
|
||||
struct list_head head;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_nodelist *ndlp = NULL;
|
||||
|
||||
lpfc_set_disctmo(vport);
|
||||
vport->num_disc_nodes = 0;
|
||||
@@ -574,19 +608,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type,
|
||||
/* Get next DID from NameServer List */
|
||||
CTentry = *ctptr++;
|
||||
Did = ((be32_to_cpu(CTentry)) & Mask_DID);
|
||||
|
||||
ndlp = NULL;
|
||||
|
||||
/*
|
||||
* Check for rscn processing or not
|
||||
* To conserve rpi's, filter out addresses for other
|
||||
* vports on the same physical HBAs.
|
||||
*/
|
||||
if ((Did != vport->fc_myDID) &&
|
||||
((lpfc_find_vport_by_did(phba, Did) == NULL) ||
|
||||
vport->cfg_peer_port_login))
|
||||
lpfc_prep_node_fc4type(vport, Did, fc4_type);
|
||||
|
||||
lpfc_ns_rsp_audit_did(vport, Did, fc4_type);
|
||||
if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY)))
|
||||
goto nsout1;
|
||||
|
||||
@@ -596,6 +618,22 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type,
|
||||
|
||||
}
|
||||
|
||||
/* All GID_FT entries processed. If the driver is running in
|
||||
* in target mode, put impacted nodes into recovery and drop
|
||||
* the RPI to flush outstanding IO.
|
||||
*/
|
||||
if (vport->phba->nvmet_support) {
|
||||
list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
|
||||
if (!(ndlp->nlp_flag & NLP_NVMET_RECOV))
|
||||
continue;
|
||||
lpfc_disc_state_machine(vport, ndlp, NULL,
|
||||
NLP_EVT_DEVICE_RECOVERY);
|
||||
spin_lock_irq(shost->host_lock);
|
||||
ndlp->nlp_flag &= ~NLP_NVMET_RECOV;
|
||||
spin_lock_irq(shost->host_lock);
|
||||
}
|
||||
}
|
||||
|
||||
nsout1:
|
||||
list_del(&head);
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user