Skip to content

Commit 1f0f767

Browse files
Justin Teemartinkpetersen
authored andcommitted
scsi: lpfc: Update PRLO handling in direct attached topology
A kref imbalance occurs when handling an unsolicited PRLO in direct attached topology. Rework PRLO rcv handling when in MAPPED state. Save the state that we were handling a PRLO by setting nlp_last_elscmd to ELS_CMD_PRLO. Then in the lpfc_cmpl_els_logo_acc() completion routine, manually restart discovery. By issuing the PLOGI, which nlp_gets, before nlp_put at the end of the lpfc_cmpl_els_logo_acc() routine, we are saving us from a final nlp_put. And, we are still allowing the unreg_rpi to happen. Signed-off-by: Justin Tee <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent b5c18c9 commit 1f0f767

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

drivers/scsi/lpfc/lpfc_els.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5246,9 +5246,10 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
52465246
/* ACC to LOGO completes to NPort <nlp_DID> */
52475247
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
52485248
"0109 ACC to LOGO completes to NPort x%x refcnt %d "
5249-
"Data: x%x x%x x%x\n",
5250-
ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp->nlp_flag,
5251-
ndlp->nlp_state, ndlp->nlp_rpi);
5249+
"last els x%x Data: x%x x%x x%x\n",
5250+
ndlp->nlp_DID, kref_read(&ndlp->kref),
5251+
ndlp->nlp_last_elscmd, ndlp->nlp_flag, ndlp->nlp_state,
5252+
ndlp->nlp_rpi);
52525253

52535254
/* This clause allows the LOGO ACC to complete and free resources
52545255
* for the Fabric Domain Controller. It does deliberately skip
@@ -5260,18 +5261,22 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
52605261
goto out;
52615262

52625263
if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
5263-
/* If PLOGI is being retried, PLOGI completion will cleanup the
5264-
* node. The NLP_NPR_2B_DISC flag needs to be retained to make
5265-
* progress on nodes discovered from last RSCN.
5266-
*/
5267-
if ((ndlp->nlp_flag & NLP_DELAY_TMO) &&
5268-
(ndlp->nlp_last_elscmd == ELS_CMD_PLOGI))
5269-
goto out;
5270-
52715264
if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
52725265
lpfc_unreg_rpi(vport, ndlp);
52735266

5267+
/* If came from PRLO, then PRLO_ACC is done.
5268+
* Start rediscovery now.
5269+
*/
5270+
if (ndlp->nlp_last_elscmd == ELS_CMD_PRLO) {
5271+
spin_lock_irq(&ndlp->lock);
5272+
ndlp->nlp_flag |= NLP_NPR_2B_DISC;
5273+
spin_unlock_irq(&ndlp->lock);
5274+
ndlp->nlp_prev_state = ndlp->nlp_state;
5275+
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
5276+
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
5277+
}
52745278
}
5279+
52755280
out:
52765281
/*
52775282
* The driver received a LOGO from the rport and has ACK'd it.

drivers/scsi/lpfc/lpfc_nportdisc.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,8 +2652,26 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
26522652
/* flush the target */
26532653
lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT);
26542654

2655-
/* Treat like rcv logo */
2656-
lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
2655+
/* Send PRLO_ACC */
2656+
spin_lock_irq(&ndlp->lock);
2657+
ndlp->nlp_flag |= NLP_LOGO_ACC;
2658+
spin_unlock_irq(&ndlp->lock);
2659+
lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
2660+
2661+
/* Save ELS_CMD_PRLO as the last elscmd and then set to NPR.
2662+
* lpfc_cmpl_els_logo_acc is expected to restart discovery.
2663+
*/
2664+
ndlp->nlp_last_elscmd = ELS_CMD_PRLO;
2665+
ndlp->nlp_prev_state = ndlp->nlp_state;
2666+
2667+
lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_ELS | LOG_DISCOVERY,
2668+
"3422 DID x%06x nflag x%x lastels x%x ref cnt %u\n",
2669+
ndlp->nlp_DID, ndlp->nlp_flag,
2670+
ndlp->nlp_last_elscmd,
2671+
kref_read(&ndlp->kref));
2672+
2673+
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2674+
26572675
return ndlp->nlp_state;
26582676
}
26592677

0 commit comments

Comments
 (0)