lkml.org 
[lkml]   [2021]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 786/800] scsi: lpfc: Fix Node recovery when driver is handling simultaneous PLOGIs
    Date
    From: James Smart <jsmart2021@gmail.com>

    commit 4012baeab6ca22b7f7beb121b6d0da0a62942fdd upstream.

    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: 52edb2caf675 ("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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/scsi/lpfc/lpfc_els.c | 21 ++++++++++++++++++---
    1 file changed, 18 insertions(+), 3 deletions(-)

    --- a/drivers/scsi/lpfc/lpfc_els.c
    +++ b/drivers/scsi/lpfc/lpfc_els.c
    @@ -1998,9 +1998,20 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phb
    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);
    @@ -4620,6 +4631,10 @@ out:
    (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);
    }


    \
     
     \ /
      Last update: 2021-07-12 11:09    [W:2.101 / U:0.296 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site