scsi: qla2xxx: Add retry limit for fabric scan logic
authorQuinn Tran <quinn.tran@cavium.com>
Thu, 28 Dec 2017 20:33:39 +0000 (12:33 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 4 Jan 2018 04:41:07 +0000 (23:41 -0500)
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>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_isr.c

index 0d20f5f..99d2afa 100644 (file)
@@ -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;
 };
index 963ebcb..8e09f6f 100644 (file)
@@ -3875,13 +3875,17 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
 
        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_host_t *vha, srb_t *sp)
 
 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_done(void *s, int res)
        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;
        }
 
index 67434b9..a37a2a4 100644 (file)
@@ -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);