Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: lpfc: Revise NPIV ELS unsol rcv cmpl logic to drop ndlp based on nlp_state

When NPIV ports are zoned to devices that support both initiator and target
mode, a remote device's initiated PRLI results in unintended final kref
clean up of the device's ndlp structure. This disrupts NPIV ports'
discovery for target devices that support both initiator and target mode.

Modify the NPIV lpfc_drop_node clause such that we allow the ndlp to live
so long as it was in NLP_STE_PLOGI_ISSUE, NLP_STE_REG_LOGIN_ISSUE, or
NLP_STE_PRLI_ISSUE nlp_state. This allows lpfc's issued PRLI completion
routine to determine if the final kref clean up should execute rather than
a remote device's issued PRLI.

Fixes: db651ec22524 ("scsi: lpfc: Correct used_rpi count when devloss tmo fires with no recovery")
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20230523183206.7728-5-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Justin Tee and committed by
Martin K. Petersen
9914a3d0 73ded378

+12 -2
+12 -2
drivers/scsi/lpfc/lpfc_els.c
··· 5452 5452 ndlp->nlp_flag &= ~NLP_RELEASE_RPI; 5453 5453 spin_unlock_irq(&ndlp->lock); 5454 5454 } 5455 + lpfc_drop_node(vport, ndlp); 5456 + } else if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE && 5457 + ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE && 5458 + ndlp->nlp_state != NLP_STE_PRLI_ISSUE) { 5459 + /* Drop ndlp if there is no planned or outstanding 5460 + * issued PRLI. 5461 + * 5462 + * In cases when the ndlp is acting as both an initiator 5463 + * and target function, let our issued PRLI determine 5464 + * the final ndlp kref drop. 5465 + */ 5466 + lpfc_drop_node(vport, ndlp); 5455 5467 } 5456 - 5457 - lpfc_drop_node(vport, ndlp); 5458 5468 } 5459 5469 5460 5470 /* Release the originating I/O reference. */