]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
scsi: lpfc: Linux LPFC driver does not process all RSCNs
authorJames Smart <jsmart2021@gmail.com>
Tue, 21 Nov 2017 00:00:38 +0000 (16:00 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 5 Dec 2017 01:32:54 +0000 (20:32 -0500)
During RSCN storms, the driver does not rediscover some targets.  The
driver marks some RSCN as to be handled after the ones it's working
on. The driver missed processing some deferred RSCN.

Move where the driver checks for deferred RSCNs and initiate deferred
RSCN handling if the flag was set. Also revise nport state within the
RSCN confirm routine. Add some state data to a possible debug print to
aid future debugging.

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c

index f77673ab4a8445b8a3ec34816c21727c1b0804f1..2c1fe5ab3128236d9ade620c69b123a92957e607 100644 (file)
@@ -685,6 +685,25 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        lpfc_els_flush_rscn(vport);
                goto out;
        }
+
+       spin_lock_irq(shost->host_lock);
+       if (vport->fc_flag & FC_RSCN_DEFERRED) {
+               vport->fc_flag &= ~FC_RSCN_DEFERRED;
+               spin_unlock_irq(shost->host_lock);
+
+               /*
+                * Skip processing the NS response
+                * Re-issue the NS cmd
+                */
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                                "0151 Process Deferred RSCN Data: x%x x%x\n",
+                                vport->fc_flag, vport->fc_rscn_id_cnt);
+               lpfc_els_handle_rscn(vport);
+
+               goto out;
+       }
+       spin_unlock_irq(shost->host_lock);
+
        if (irsp->ulpStatus) {
                /* Check for retry */
                if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
index 95733981828d48424f9d443e4723b40a460a9bf1..4a14f3c82a07747d56812f2c1808c21ee6a1101c 100644 (file)
@@ -1675,6 +1675,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 
                /* Two ndlps cannot have the same did on the nodelist */
                ndlp->nlp_DID = keepDID;
+               lpfc_nlp_set_state(vport, ndlp, keep_nlp_state);
                if (phba->sli_rev == LPFC_SLI_REV4 &&
                    active_rrqs_xri_bitmap)
                        memcpy(ndlp->active_rrqs_xri_bitmap,
@@ -6177,9 +6178,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
                /* send RECOVERY event for ALL nodes that match RSCN payload */
                lpfc_rscn_recovery_check(vport);
-               spin_lock_irq(shost->host_lock);
-               vport->fc_flag &= ~FC_RSCN_DEFERRED;
-               spin_unlock_irq(shost->host_lock);
                return 0;
        }
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
index 0b2c542011a331dd6379a805f4143d58077e523f..8d14c99edf209e83af7b3d4ce454bf02a3716c90 100644 (file)
@@ -5836,9 +5836,12 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
                if (filter(ndlp, param)) {
                        lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
                                         "3185 FIND node filter %p DID "
-                                        "Data: x%p x%x x%x\n",
+                                        "ndlp %p did x%x flg x%x st x%x "
+                                        "xri x%x type x%x rpi x%x\n",
                                         filter, ndlp, ndlp->nlp_DID,
-                                        ndlp->nlp_flag);
+                                        ndlp->nlp_flag, ndlp->nlp_state,
+                                        ndlp->nlp_xri, ndlp->nlp_type,
+                                        ndlp->nlp_rpi);
                        return ndlp;
                }
        }