Skip to content

Commit 7f4c5a2

Browse files
jsmart-ghmartinkpetersen
authored andcommitted
scsi: lpfc: Fix pt2pt NVMe PRLI reject LOGO loop
When connected point to point, the driver does not know the FC4's supported by the other end. In Fabrics, it can query the nameserver. Thus the driver must send PRLIs for the FC4s it supports and enable support based on the acc(ept) or rej(ect) of the respective FC4 PRLI. Currently the driver supports SCSI and NVMe PRLIs. Unfortunately, although the behavior is per standard, many devices have come to expect only SCSI PRLIs. In this particular example, the NVMe PRLI is properly RJT'd but the target decided that it must LOGO after seeing the unexpected NVMe PRLI. The LOGO causes the sequence to restart and login is now in an infinite failure loop. Fix the problem by having the driver, on a pt2pt link, remember NVMe PRLI accept or reject status across logout as long as the link stays "up". When retrying login, if the prior NVMe PRLI was rejected, it will not be sent on the next login. Link: https://lore.kernel.org/r/20220212163120.15385-1-jsmart2021@gmail.com Cc: <stable@vger.kernel.org> # v5.4+ Reviewed-by: Ewan D. Milne <emilne@redhat.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent f10f582 commit 7f4c5a2

4 files changed

Lines changed: 26 additions & 3 deletions

File tree

drivers/scsi/lpfc/lpfc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ struct lpfc_vport {
592592
#define FC_VPORT_LOGO_RCVD 0x200 /* LOGO received on vport */
593593
#define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */
594594
#define FC_LOGO_RCVD_DID_CHNG 0x800 /* FDISC on phys port detect DID chng*/
595+
#define FC_PT2PT_NO_NVME 0x1000 /* Don't send NVME PRLI */
595596
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
596597
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
597598
#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */

drivers/scsi/lpfc/lpfc_attr.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,9 @@ lpfc_issue_lip(struct Scsi_Host *shost)
13151315
pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
13161316
pmboxq->u.mb.mbxOwner = OWN_HOST;
13171317

1318+
if ((vport->fc_flag & FC_PT2PT) && (vport->fc_flag & FC_PT2PT_NO_NVME))
1319+
vport->fc_flag &= ~FC_PT2PT_NO_NVME;
1320+
13181321
mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2);
13191322

13201323
if ((mbxstatus == MBX_SUCCESS) &&

drivers/scsi/lpfc/lpfc_els.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
10721072

10731073
/* FLOGI failed, so there is no fabric */
10741074
spin_lock_irq(shost->host_lock);
1075-
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
1075+
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP |
1076+
FC_PT2PT_NO_NVME);
10761077
spin_unlock_irq(shost->host_lock);
10771078

10781079
/* If private loop, then allow max outstanding els to be
@@ -4607,6 +4608,23 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
46074608
/* Added for Vendor specifc support
46084609
* Just keep retrying for these Rsn / Exp codes
46094610
*/
4611+
if ((vport->fc_flag & FC_PT2PT) &&
4612+
cmd == ELS_CMD_NVMEPRLI) {
4613+
switch (stat.un.b.lsRjtRsnCode) {
4614+
case LSRJT_UNABLE_TPC:
4615+
case LSRJT_INVALID_CMD:
4616+
case LSRJT_LOGICAL_ERR:
4617+
case LSRJT_CMD_UNSUPPORTED:
4618+
lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
4619+
"0168 NVME PRLI LS_RJT "
4620+
"reason %x port doesn't "
4621+
"support NVME, disabling NVME\n",
4622+
stat.un.b.lsRjtRsnCode);
4623+
retry = 0;
4624+
vport->fc_flag |= FC_PT2PT_NO_NVME;
4625+
goto out_retry;
4626+
}
4627+
}
46104628
switch (stat.un.b.lsRjtRsnCode) {
46114629
case LSRJT_UNABLE_TPC:
46124630
/* The driver has a VALID PLOGI but the rport has

drivers/scsi/lpfc/lpfc_nportdisc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,8 +1961,9 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
19611961
* is configured try it.
19621962
*/
19631963
ndlp->nlp_fc4_type |= NLP_FC4_FCP;
1964-
if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
1965-
(vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
1964+
if ((!(vport->fc_flag & FC_PT2PT_NO_NVME)) &&
1965+
(vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH ||
1966+
vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
19661967
ndlp->nlp_fc4_type |= NLP_FC4_NVME;
19671968
/* We need to update the localport also */
19681969
lpfc_nvme_update_localport(vport);

0 commit comments

Comments
 (0)