]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: lpfc: Ensure PLOGI_ACC is sent prior to PRLI in Point to Point topology
authorJustin Tee <justin.tee@broadcom.com>
Mon, 15 Sep 2025 18:08:04 +0000 (11:08 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 17 Sep 2025 02:19:59 +0000 (22:19 -0400)
There is a timing race condition when a PRLI may be sent on the wire
before PLOGI_ACC in Point to Point topology.  Fix by deferring REG_RPI
mbox completion handling to after PLOGI_ACC's CQE completion.  Because
the discovery state machine only sends PRLI after REG_RPI mbox
completion, PRLI is now guaranteed to be sent after PLOGI_ACC.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Message-ID: <20250915180811.137530-8-justintee8345@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_nportdisc.c

index 3f703932b2f07a0eb9a464787afdde7af8297af3..8762fb84f14f1e2fbeaaf44af03f85b7691f2b7a 100644 (file)
@@ -5339,12 +5339,12 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                ulp_status, ulp_word4, did);
        /* ELS response tag <ulpIoTag> completes */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-                        "0110 ELS response tag x%x completes "
+                        "0110 ELS response tag x%x completes fc_flag x%lx"
                         "Data: x%x x%x x%x x%x x%lx x%x x%x x%x %p %p\n",
-                        iotag, ulp_status, ulp_word4, tmo,
+                        iotag, vport->fc_flag, ulp_status, ulp_word4, tmo,
                         ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
                         ndlp->nlp_rpi, kref_read(&ndlp->kref), mbox, ndlp);
-       if (mbox) {
+       if (mbox && !test_bit(FC_PT2PT, &vport->fc_flag)) {
                if (ulp_status == 0 &&
                    test_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag)) {
                        if (!lpfc_unreg_rpi(vport, ndlp) &&
@@ -5403,6 +5403,10 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                }
 out_free_mbox:
                lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
+       } else if (mbox && test_bit(FC_PT2PT, &vport->fc_flag) &&
+                  test_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag)) {
+               lpfc_mbx_cmpl_reg_login(phba, mbox);
+               clear_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag);
        }
 out:
        if (ndlp && shost) {
index a596b80d03d4d816908b77bb469dfd0c1868c102..3799bdf2f1b88ae09383c556e4839eae6acf3212 100644 (file)
@@ -326,8 +326,14 @@ lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
                /* Now that REG_RPI completed successfully,
                 * we can now proceed with sending the PLOGI ACC.
                 */
-               rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
-                                     save_iocb, ndlp, NULL);
+               if (test_bit(FC_PT2PT, &ndlp->vport->fc_flag)) {
+                       rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
+                                             save_iocb, ndlp, login_mbox);
+               } else {
+                       rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,
+                                             save_iocb, ndlp, NULL);
+               }
+
                if (rc) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
                                        "4576 PLOGI ACC fails pt2pt discovery: "
@@ -335,9 +341,16 @@ lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
                }
        }
 
-       /* Now process the REG_RPI cmpl */
-       lpfc_mbx_cmpl_reg_login(phba, login_mbox);
-       clear_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag);
+       /* If this is a fabric topology, complete the reg_rpi and prli now.
+        * For Pt2Pt, the reg_rpi and PRLI are deferred until after the LS_ACC
+        * completes.  This ensures, in Pt2Pt, that the PLOGI LS_ACC is sent
+        * before the PRLI.
+        */
+       if (!test_bit(FC_PT2PT, &ndlp->vport->fc_flag)) {
+               /* Now process the REG_RPI cmpl */
+               lpfc_mbx_cmpl_reg_login(phba, login_mbox);
+               clear_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag);
+       }
        kfree(save_iocb);
 }