scsi: qla2xxx: Reduce redundant ADISC command for RSCNs
authorQuinn Tran <quinn.tran@cavium.com>
Tue, 1 May 2018 16:01:47 +0000 (09:01 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 8 May 2018 04:46:11 +0000 (00:46 -0400)
For each RSCN that triggers a rescan of the fabric, ADISC is used to
revalidate an existing session. If the RSCN is not affecting all
existing sessions, then driver should not send redundant ADISC for all
existing sessions.

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_init.c

index eb2ec1fb07cbe7a6f2118b0504e2e3bde76374ae..5a1900ec808d16805b19b79488381e9e2738a495 100644 (file)
@@ -2346,6 +2346,7 @@ typedef struct fc_port {
        unsigned int login_succ:1;
        unsigned int query:1;
        unsigned int id_changed:1;
+       unsigned int rscn_rcvd:1;
 
        struct work_struct nvme_del_work;
        struct completion nvme_del_done;
index 05abe5aaab7f5024ee4d4b2dea1d849eec7c655f..939ac8435f1973f1c7cf425d20341049bbd2aeaf 100644 (file)
@@ -3862,6 +3862,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
        bool found;
        struct fab_scan_rp *rp;
        unsigned long flags;
+       u8 recheck = 0;
 
        ql_dbg(ql_dbg_disc, vha, 0xffff,
            "%s enter\n", __func__);
@@ -3914,6 +3915,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
                list_for_each_entry(fcport, &vha->vp_fcports, list) {
                        if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
                                continue;
+                       fcport->rscn_rcvd = 0;
                        fcport->scan_state = QLA_FCPORT_FOUND;
                        found = true;
                        /*
@@ -3942,10 +3944,13 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
         * Logout all previous fabric dev marked lost, except FCP2 devices.
         */
        list_for_each_entry(fcport, &vha->vp_fcports, list) {
-               if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
+               if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
+                       fcport->rscn_rcvd = 0;
                        continue;
+               }
 
                if (fcport->scan_state != QLA_FCPORT_FOUND) {
+                       fcport->rscn_rcvd = 0;
                        if ((qla_dual_mode_enabled(vha) ||
                                qla_ini_mode_enabled(vha)) &&
                            atomic_read(&fcport->state) == FCS_ONLINE) {
@@ -3963,15 +3968,31 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
                                        continue;
                                }
                        }
-               } else
-                       qla24xx_fcport_handle_login(vha, fcport);
+               } else {
+                       if (fcport->rscn_rcvd ||
+                           fcport->disc_state != DSC_LOGIN_COMPLETE) {
+                               fcport->rscn_rcvd = 0;
+                               qla24xx_fcport_handle_login(vha, fcport);
+                       }
+               }
        }
 
+       recheck = 1;
 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);
+
+       if (recheck) {
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->rscn_rcvd) {
+                               set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
+                               set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+                               break;
+                       }
+               }
+       }
 }
 
 static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
index b9050cb52c0eca8d40be22cfcd68df6c67d15b31..98d4b315d66a3a37586567918977cc462c3d8569 100644 (file)
@@ -1348,6 +1348,7 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
        fc_port_t *f, *tf;
        uint32_t id = 0, mask, rid;
        unsigned long flags;
+       fc_port_t *fcport;
 
        switch (ea->event) {
        case FCME_RSCN:
@@ -1375,6 +1376,11 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
                        return;
                switch (ea->id.b.rsvd_1) {
                case RSCN_PORT_ADDR:
+                       fcport = qla2x00_find_fcport_by_nportid
+                               (vha, &ea->id, 1);
+                       if (fcport)
+                               fcport->rscn_rcvd = 1;
+
                        spin_lock_irqsave(&vha->work_lock, flags);
                        if (vha->scan.scan_flags == 0) {
                                ql_dbg(ql_dbg_disc, vha, 0xffff,