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 f77673a..2c1fe5a 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 9573398..4a14f3c 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 0b2c542..8d14c99 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;
                }
        }