Blob Blame History Raw
From: Quinn Tran <quinn.tran@cavium.com>
Date: Thu, 28 Dec 2017 12:33:39 -0800
Subject: scsi: qla2xxx: Add retry limit for fabric scan logic
Patch-mainline: v4.16-rc1
Git-commit: 6944dccbb7c9dbcd25f9e8f8308a384ff5a464e0
References: bsc#1077338

Switch scan is assumed to succeed most of the time.
If the scan failed, then scan is limit 5 retries.

Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
---
 drivers/scsi/qla2xxx/qla_def.h |    2 ++
 drivers/scsi/qla2xxx/qla_gs.c  |   32 ++++++++++++++++++++------------
 drivers/scsi/qla2xxx/qla_isr.c |    1 +
 3 files changed, 23 insertions(+), 12 deletions(-)

--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2986,6 +2986,8 @@ struct fab_scan_rp {
 struct fab_scan {
 	struct fab_scan_rp *l;
 	u32 size;
+	u16 scan_retry;
+#define MAX_SCAN_RETRIES 5
 	enum scan_flags_t scan_flags;
 	struct delayed_work scan_work;
 };
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3875,13 +3875,17 @@ void qla24xx_async_gnnft_done(scsi_qla_h
 
 	rc = sp->rc;
 	if (rc) {
-		ql_dbg(ql_dbg_disc, vha, 0xffff,
-		    "GPNFT failed. FC4type %x. Rescanning.\n",
-		    fc4type);
-		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
-		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+		vha->scan.scan_retry++;
+		if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
+			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+		} else {
+			ql_dbg(ql_dbg_disc, vha, 0xffff,
+			    "Fabric scan failed on all retries.\n");
+		}
 		goto out;
 	}
+	vha->scan.scan_retry = 0;
 
 	list_for_each_entry(fcport, &vha->vp_fcports, list)
 		fcport->scan_state = QLA_FCPORT_SCAN;
@@ -3964,7 +3968,6 @@ void qla24xx_async_gnnft_done(scsi_qla_h
 
 out:
 	qla24xx_sp_unmap(vha, sp);
-
 	spin_lock_irqsave(&vha->work_lock, flags);
 	vha->scan.scan_flags &= ~SF_SCANNING;
 	spin_unlock_irqrestore(&vha->work_lock, flags);
@@ -3992,16 +3995,21 @@ static void qla2x00_async_gpnft_gnnft_sp
 	if (res) {
 		unsigned long flags;
 
-		ql_dbg(ql_dbg_disc, sp->vha, 0xffff,
-		    "Async done-%s timed out.\n",
-		    sp->name);
 		sp->free(sp);
 		spin_lock_irqsave(&vha->work_lock, flags);
 		vha->scan.scan_flags &= ~SF_SCANNING;
+		vha->scan.scan_retry++;
 		spin_unlock_irqrestore(&vha->work_lock, flags);
-		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
-		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
-		qla2xxx_wake_dpc(vha);
+
+		if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
+			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+			qla2xxx_wake_dpc(vha);
+		} else {
+			ql_dbg(ql_dbg_disc, sp->vha, 0xffff,
+			    "Async done-%s rescan failed on all retries\n",
+			    sp->name);
+		}
 		return;
 	}
 
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1059,6 +1059,7 @@ global_port_update:
 		 * Mark all devices as missing so we will login again.
 		 */
 		atomic_set(&vha->loop_state, LOOP_UP);
+		vha->scan.scan_retry = 0;
 
 		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
 		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);