Skip to content

Commit

Permalink
scsi: lpfc: Fix Node recovery when driver is handling simultaneous PL…
Browse files Browse the repository at this point in the history
…OGIs

When lpfc is handling a solicited and unsolicited PLOGI with another
initiator, the remote initiator is never recovered. The node for the
initiator is erroneouosly removed and all resources released.

In lpfc_cmpl_els_plogi(), when lpfc_els_retry() returns a failure code, the
driver is calling the state machine with a device remove event because the
remote port is not currently registered with the SCSI or NVMe
transports. The issue is that on a PLOGI "collision" the driver correctly
aborts the solicited PLOGI and allows the unsolicited PLOGI to complete the
process, but this process is interrupted with a device_rm event.

Introduce logic in the PLOGI completion to capture the PLOGI collision
event and jump out of the routine.  This will avoid removal of the node.
If there is no collision, the normal node removal will occur.

Fixes: 	52edb2c ("scsi: lpfc: Remove ndlp when a PLOGI/ADISC/PRLI/REG_RPI ultimately fails")
Cc: <stable@vger.kernel.org> # v5.11+
Link: https://lore.kernel.org/r/20210514195559.119853-6-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
James Smart authored and Martin K. Petersen committed May 22, 2021
1 parent 1037e4b commit 4012bae
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions drivers/scsi/lpfc/lpfc_els.c
Original file line number Diff line number Diff line change
Expand Up @@ -2007,9 +2007,20 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_CMPL_PLOGI);

/* As long as this node is not registered with the scsi or nvme
* transport, it is no longer an active node. Otherwise
* devloss handles the final cleanup.
/* If a PLOGI collision occurred, the node needs to continue
* with the reglogin process.
*/
spin_lock_irq(&ndlp->lock);
if ((ndlp->nlp_flag & (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI)) &&
ndlp->nlp_state == NLP_STE_REG_LOGIN_ISSUE) {
spin_unlock_irq(&ndlp->lock);
goto out;
}
spin_unlock_irq(&ndlp->lock);

/* No PLOGI collision and the node is not registered with the
* scsi or nvme transport. It is no longer an active node. Just
* start the device remove process.
*/
if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) {
spin_lock_irq(&ndlp->lock);
Expand Down Expand Up @@ -4629,6 +4640,10 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
(vport && vport->port_type == LPFC_NPIV_PORT) &&
ndlp->nlp_flag & NLP_RELEASE_RPI) {
lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
spin_lock_irq(&ndlp->lock);
ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR;
ndlp->nlp_flag &= ~NLP_RELEASE_RPI;
spin_unlock_irq(&ndlp->lock);
lpfc_drop_node(vport, ndlp);
}

Expand Down

0 comments on commit 4012bae

Please sign in to comment.