summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
authorJustin Tee <justin.tee@broadcom.com>2024-07-27 02:15:09 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2024-08-03 04:48:05 +0300
commitb5c18c9dd138733c16893613345af44deadcf05e (patch)
tree56db97fbcebec977cfb1553860143c1a5acfd1e3 /drivers/scsi/lpfc/lpfc_hbadisc.c
parent3976beb1b410441bab9c3726e2ba76cc7a4c0b2d (diff)
downloadlinux-b5c18c9dd138733c16893613345af44deadcf05e.tar.xz
scsi: lpfc: Fix unsolicited FLOGI kref imbalance when in direct attached topology
In direct attached topology, certain target vendors that are quick to issue FLOGI followed by a cable pull for more than dev_loss_tmo may result in a kref imbalance for the remote port ndlp object. Add an nlp_get when the defer_flogi_acc flag is set. This is expected to balance the nlp_put in the defer_flogi_acc clause in the lpfc_issue_els_flogi() routine. Because we need to retain the ndlp ptr, reorganize all of the defer_flogi_acc information into one lpfc_defer_flogi_acc struct. Signed-off-by: Justin Tee <justin.tee@broadcom.com> Link: https://lore.kernel.org/r/20240726231512.92867-6-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index f21c5993e8d7..35c9181c6608 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1255,7 +1255,14 @@ lpfc_linkdown(struct lpfc_hba *phba)
lpfc_scsi_dev_block(phba);
offline = pci_channel_offline(phba->pcidev);
- phba->defer_flogi_acc_flag = false;
+ /* Decrement the held ndlp if there is a deferred flogi acc */
+ if (phba->defer_flogi_acc.flag) {
+ if (phba->defer_flogi_acc.ndlp) {
+ lpfc_nlp_put(phba->defer_flogi_acc.ndlp);
+ phba->defer_flogi_acc.ndlp = NULL;
+ }
+ }
+ phba->defer_flogi_acc.flag = false;
/* Clear external loopback plug detected flag */
phba->link_flag &= ~LS_EXTERNAL_LOOPBACK;
@@ -1377,7 +1384,7 @@ lpfc_linkup_port(struct lpfc_vport *vport)
(vport != phba->pport))
return;
- if (phba->defer_flogi_acc_flag) {
+ if (phba->defer_flogi_acc.flag) {
clear_bit(FC_ABORT_DISCOVERY, &vport->fc_flag);
clear_bit(FC_RSCN_MODE, &vport->fc_flag);
clear_bit(FC_NLP_MORE, &vport->fc_flag);