scsi: qla2xxx: Remove ASYNC GIDPN switch command
authorHimanshu Madhani <himanshu.madhani@cavium.com>
Tue, 4 Sep 2018 21:19:17 +0000 (14:19 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 12 Sep 2018 00:28:08 +0000 (20:28 -0400)
Using GPNFT/GNNFT command will be able to cover switch database with less
number of scans. This patch removes Get NportID with provided WWPN/GIDPN
switch command. By making this change, in large fabric with lots of remote
port or NPIV ports with noisy SAN, the number of GIDPN commands issued by a
port when it detects large number of remote ports going away or coming back,
can overwhelmn the switch and it can becomde unresponsive. In a case where the
fabric has not change, GIDPN is not required.

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_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_os.c

index 8b8c7c8db1ca468a33458af508fa0d424440bc9e..0a1cae0153b0ad2f9c4c08c24cf6cf1feafcbd28 100644 (file)
@@ -2281,7 +2281,6 @@ struct ct_sns_desc {
 enum discovery_state {
        DSC_DELETED,
        DSC_GNN_ID,
-       DSC_GID_PN,
        DSC_GNL,
        DSC_LOGIN_PEND,
        DSC_LOGIN_FAILED,
@@ -2306,7 +2305,6 @@ enum login_state {        /* FW control Target side */
 enum fcport_mgt_event {
        FCME_RELOGIN = 1,
        FCME_RSCN,
-       FCME_GIDPN_DONE,
        FCME_PLOGI_DONE,        /* Initiator side sent LLIOCB */
        FCME_PRLI_DONE,
        FCME_GNL_DONE,
@@ -3219,7 +3217,6 @@ enum qla_work_type {
        QLA_EVT_ASYNC_ADISC_DONE,
        QLA_EVT_UEVENT,
        QLA_EVT_AENFX,
-       QLA_EVT_GIDPN,
        QLA_EVT_GPNID,
        QLA_EVT_UNMAP,
        QLA_EVT_NEW_SESS,
index b8e4abe804d5d3df7fe9d069a59ff3e68aa9ea64..db642ea5358f92ba8215ea22262528d27a063a74 100644 (file)
@@ -119,6 +119,8 @@ extern int qla2x00_post_async_prlo_done_work(struct scsi_qla_host *,
 int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
 void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
 int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *);
+void qla_rscn_replay(fc_port_t *fcport);
+
 /*
  * Global Data in qla_os.c source file.
  */
@@ -645,9 +647,6 @@ extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *, size_t);
 extern int qla2x00_chk_ms_status(scsi_qla_host_t *, ms_iocb_entry_t *,
        struct ct_sns_rsp *, const char *);
 extern void qla2x00_async_iocb_timeout(void *data);
-extern int qla24xx_async_gidpn(scsi_qla_host_t *, fc_port_t *);
-int qla24xx_post_gidpn_work(struct scsi_qla_host *, fc_port_t *);
-void qla24xx_handle_gidpn_event(scsi_qla_host_t *, struct event_arg *);
 
 extern void qla2x00_free_fcport(fc_port_t *);
 
index 3c8882a3e6bcf1143d05bc1063fb737ccdef5be9..56a80c6e50e38002533d218b4bd9b6f3fcc9b3cd 100644 (file)
@@ -2973,237 +2973,6 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
        }
 }
 
-/* GID_PN completion processing. */
-void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea)
-{
-       fc_port_t *fcport = ea->fcport;
-
-       ql_dbg(ql_dbg_disc, vha, 0x201d,
-           "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
-           __func__, fcport->port_name, fcport->disc_state,
-           fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
-           fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);
-
-       if (fcport->disc_state == DSC_DELETE_PEND)
-               return;
-
-       if (ea->sp->gen2 != fcport->login_gen) {
-               /* PLOGI/PRLI/LOGO came in while cmd was out.*/
-               ql_dbg(ql_dbg_disc, vha, 0x201e,
-                   "%s %8phC generation changed rscn %d|%d n",
-                   __func__, fcport->port_name, fcport->last_rscn_gen,
-                   fcport->rscn_gen);
-               return;
-       }
-
-       if (!ea->rc) {
-               if (ea->sp->gen1 == fcport->rscn_gen) {
-                       fcport->scan_state = QLA_FCPORT_FOUND;
-                       fcport->flags |= FCF_FABRIC_DEVICE;
-
-                       if (fcport->d_id.b24 == ea->id.b24) {
-                               /* cable plugged into the same place */
-                               switch (vha->host->active_mode) {
-                               case MODE_TARGET:
-                                       if (fcport->fw_login_state ==
-                                           DSC_LS_PRLI_COMP) {
-                                               u16 data[2];
-                                               /*
-                                                * Late RSCN was delivered.
-                                                * Remote port already login'ed.
-                                                */
-                                               ql_dbg(ql_dbg_disc, vha, 0x201f,
-                                                   "%s %d %8phC post adisc\n",
-                                                   __func__, __LINE__,
-                                                   fcport->port_name);
-                                               data[0] = data[1] = 0;
-                                               qla2x00_post_async_adisc_work(
-                                                   vha, fcport, data);
-                                       }
-                                       break;
-                               case MODE_INITIATOR:
-                               case MODE_DUAL:
-                               default:
-                                       ql_dbg(ql_dbg_disc, vha, 0x201f,
-                                           "%s %d %8phC post %s\n", __func__,
-                                           __LINE__, fcport->port_name,
-                                           (atomic_read(&fcport->state) ==
-                                           FCS_ONLINE) ? "adisc" : "gnl");
-
-                                       if (atomic_read(&fcport->state) ==
-                                           FCS_ONLINE) {
-                                               u16 data[2];
-
-                                               data[0] = data[1] = 0;
-                                               qla2x00_post_async_adisc_work(
-                                                   vha, fcport, data);
-                                       } else {
-                                               qla24xx_post_gnl_work(vha,
-                                                   fcport);
-                                       }
-                                       break;
-                               }
-                       } else { /* fcport->d_id.b24 != ea->id.b24 */
-                               fcport->d_id.b24 = ea->id.b24;
-                               fcport->id_changed = 1;
-                               if (fcport->deleted != QLA_SESS_DELETED) {
-                                       ql_dbg(ql_dbg_disc, vha, 0x2021,
-                                           "%s %d %8phC post del sess\n",
-                                           __func__, __LINE__, fcport->port_name);
-                                       qlt_schedule_sess_for_deletion(fcport);
-                               }
-                       }
-               } else { /* ea->sp->gen1 != fcport->rscn_gen */
-                       ql_dbg(ql_dbg_disc, vha, 0x2022,
-                           "%s %d %8phC post gidpn\n",
-                           __func__, __LINE__, fcport->port_name);
-                       /* rscn came in while cmd was out */
-                       qla24xx_post_gidpn_work(vha, fcport);
-               }
-       } else { /* ea->rc */
-               /* cable pulled */
-               if (ea->sp->gen1 == fcport->rscn_gen) {
-                       if (ea->sp->gen2 == fcport->login_gen) {
-                               ql_dbg(ql_dbg_disc, vha, 0x2042,
-                                   "%s %d %8phC post del sess\n", __func__,
-                                   __LINE__, fcport->port_name);
-                               qlt_schedule_sess_for_deletion(fcport);
-                       } else {
-                               ql_dbg(ql_dbg_disc, vha, 0x2045,
-                                   "%s %d %8phC login\n", __func__, __LINE__,
-                                   fcport->port_name);
-                               qla24xx_fcport_handle_login(vha, fcport);
-                       }
-               } else {
-                       ql_dbg(ql_dbg_disc, vha, 0x2049,
-                           "%s %d %8phC post gidpn\n", __func__, __LINE__,
-                           fcport->port_name);
-                       qla24xx_post_gidpn_work(vha, fcport);
-               }
-       }
-} /* gidpn_event */
-
-static void qla2x00_async_gidpn_sp_done(void *s, int res)
-{
-       struct srb *sp = s;
-       struct scsi_qla_host *vha = sp->vha;
-       fc_port_t *fcport = sp->fcport;
-       u8 *id = fcport->ct_desc.ct_sns->p.rsp.rsp.gid_pn.port_id;
-       struct event_arg ea;
-
-       fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
-
-       memset(&ea, 0, sizeof(ea));
-       ea.fcport = fcport;
-       ea.id.b.domain = id[0];
-       ea.id.b.area = id[1];
-       ea.id.b.al_pa = id[2];
-       ea.sp = sp;
-       ea.rc = res;
-       ea.event = FCME_GIDPN_DONE;
-
-       if (res == QLA_FUNCTION_TIMEOUT) {
-               ql_dbg(ql_dbg_disc, sp->vha, 0xffff,
-                   "Async done-%s WWPN %8phC timed out.\n",
-                   sp->name, fcport->port_name);
-               qla24xx_post_gidpn_work(sp->vha, fcport);
-               sp->free(sp);
-               return;
-       } else if (res) {
-               ql_dbg(ql_dbg_disc, sp->vha, 0xffff,
-                   "Async done-%s fail res %x, WWPN %8phC\n",
-                   sp->name, res, fcport->port_name);
-       } else {
-               ql_dbg(ql_dbg_disc, vha, 0x204f,
-                   "Async done-%s good WWPN %8phC ID %3phC\n",
-                   sp->name, fcport->port_name, id);
-       }
-
-       qla2x00_fcport_event_handler(vha, &ea);
-
-       sp->free(sp);
-}
-
-int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport)
-{
-       int rval = QLA_FUNCTION_FAILED;
-       struct ct_sns_req       *ct_req;
-       srb_t *sp;
-
-       if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
-               return rval;
-
-       fcport->disc_state = DSC_GID_PN;
-       fcport->scan_state = QLA_FCPORT_SCAN;
-       sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
-       if (!sp)
-               goto done;
-
-       fcport->flags |= FCF_ASYNC_SENT;
-       sp->type = SRB_CT_PTHRU_CMD;
-       sp->name = "gidpn";
-       sp->gen1 = fcport->rscn_gen;
-       sp->gen2 = fcport->login_gen;
-
-       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
-
-       /* CT_IU preamble  */
-       ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GID_PN_CMD,
-               GID_PN_RSP_SIZE);
-
-       /* GIDPN req */
-       memcpy(ct_req->req.gid_pn.port_name, fcport->port_name,
-               WWN_SIZE);
-
-       /* req & rsp use the same buffer */
-       sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
-       sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
-       sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
-       sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
-       sp->u.iocb_cmd.u.ctarg.req_size = GID_PN_REQ_SIZE;
-       sp->u.iocb_cmd.u.ctarg.rsp_size = GID_PN_RSP_SIZE;
-       sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
-
-       sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
-       sp->done = qla2x00_async_gidpn_sp_done;
-
-       rval = qla2x00_start_sp(sp);
-       if (rval != QLA_SUCCESS)
-               goto done_free_sp;
-
-       ql_dbg(ql_dbg_disc, vha, 0x20a4,
-           "Async-%s - %8phC hdl=%x loopid=%x portid %02x%02x%02x.\n",
-           sp->name, fcport->port_name,
-           sp->handle, fcport->loop_id, fcport->d_id.b.domain,
-           fcport->d_id.b.area, fcport->d_id.b.al_pa);
-       return rval;
-
-done_free_sp:
-       sp->free(sp);
-done:
-       fcport->flags &= ~FCF_ASYNC_ACTIVE;
-       return rval;
-}
-
-int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport)
-{
-       struct qla_work_evt *e;
-       int ls;
-
-       ls = atomic_read(&vha->loop_state);
-       if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
-               test_bit(UNLOADING, &vha->dpc_flags))
-               return 0;
-
-       e = qla2x00_alloc_work(vha, QLA_EVT_GIDPN);
-       if (!e)
-               return QLA_FUNCTION_FAILED;
-
-       e->u.fcport.fcport = fcport;
-       fcport->flags |= FCF_ASYNC_ACTIVE;
-       return qla2x00_post_work(vha, e);
-}
-
 int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
 {
        struct qla_work_evt *e;
@@ -3237,9 +3006,6 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
                    __func__, fcport->port_name);
                return;
        } else if (ea->sp->gen1 != fcport->rscn_gen) {
-               ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
-                   __func__, __LINE__, fcport->port_name);
-               qla24xx_post_gidpn_work(vha, fcport);
                return;
        }
 
@@ -3466,6 +3232,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
                                qlt_schedule_sess_for_deletion(conflict);
                        }
 
+                       fcport->scan_needed = 0;
                        fcport->rscn_gen++;
                        fcport->scan_state = QLA_FCPORT_FOUND;
                        fcport->flags |= FCF_FABRIC_DEVICE;
@@ -4607,9 +4374,6 @@ void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
                    __func__, fcport->port_name);
                return;
        } else if (ea->sp->gen1 != fcport->rscn_gen) {
-               ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
-                   __func__, __LINE__, fcport->port_name);
-               qla24xx_post_gidpn_work(vha, fcport);
                return;
        }
 
index c675066b080e87133f0986a486754b9661b37ece..3fdd4336017c2225e36c4d186167aaccd21e12af 100644 (file)
@@ -413,9 +413,7 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
                    __func__, ea->fcport->port_name);
                return;
        } else if (ea->sp->gen1 != ea->fcport->rscn_gen) {
-               ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
-                   __func__, __LINE__, ea->fcport->port_name);
-               qla24xx_post_gidpn_work(vha, ea->fcport);
+               qla_rscn_replay(fcport);
                return;
        }
 
@@ -539,11 +537,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
        }
 
        if (fcport->last_rscn_gen != fcport->rscn_gen) {
-               ql_dbg(ql_dbg_disc, vha, 0x20df,
-                   "%s %8phC rscn gen changed rscn %d|%d \n",
-                   __func__, fcport->port_name,
-                   fcport->last_rscn_gen, fcport->rscn_gen);
-               qla24xx_post_gidpn_work(vha, fcport);
+               qla_rscn_replay(fcport);
                return;
        } else if (fcport->last_login_gen != fcport->login_gen) {
                ql_dbg(ql_dbg_disc, vha, 0x20e0,
@@ -1226,6 +1220,18 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
        else
                ls = pd->current_login_state & 0xf;
 
+       if (ea->sp->gen2 != fcport->login_gen) {
+               /* target side must have changed it. */
+
+               ql_dbg(ql_dbg_disc, vha, 0x20d3,
+                   "%s %8phC generation changed\n",
+                   __func__, fcport->port_name);
+               return;
+       } else if (ea->sp->gen1 != fcport->rscn_gen) {
+               qla_rscn_replay(fcport);
+               return;
+       }
+
        switch (ls) {
        case PDS_PRLI_COMPLETE:
                __qla24xx_parse_gpdb(vha, fcport, pd);
@@ -1414,7 +1420,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
                if (N2N_TOPO(vha->hw))
                        qla_chk_n2n_b4_login(vha, fcport);
                else
-                       qla24xx_post_gidpn_work(vha, fcport);
+                       qlt_schedule_sess_for_deletion(fcport);
                break;
 
        case DSC_LOGIN_COMPLETE:
@@ -1522,7 +1528,6 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
                ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n",
                    __func__, __LINE__, fcport->port_name);
 
-               qla24xx_post_gidpn_work(vha, fcport);
                return;
        }
 
@@ -1542,7 +1547,6 @@ 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) {
@@ -1557,6 +1561,10 @@ 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:
+#define BIGSCAN 1
+#if defined BIGSCAN & BIGSCAN > 0
+               {
+                       unsigned long flags;
                        fcport = qla2x00_find_fcport_by_nportid
                                (vha, &ea->id, 1);
                        if (fcport) {
@@ -1572,7 +1580,26 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
                                schedule_delayed_work(&vha->scan.scan_work, 5);
                        }
                        spin_unlock_irqrestore(&vha->work_lock, flags);
-
+               }
+#else
+               {
+                       int rc;
+                       fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
+                       if (!fcport) {
+                               /* cable moved */
+                                rc = qla24xx_post_gpnid_work(vha, &ea->id);
+                                if (rc) {
+                                        ql_log(ql_log_warn, vha, 0xd044,
+                                            "RSCN GPNID work failed %06x\n",
+                                            ea->id.b24);
+                                }
+                       } else {
+                               ea->fcport = fcport;
+                               fcport->scan_needed = 1;
+                               qla24xx_handle_rscn_event(fcport, ea);
+                       }
+               }
+#endif
                        break;
                case RSCN_AREA_ADDR:
                case RSCN_DOM_ADDR:
@@ -1608,9 +1635,6 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
                        set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
                }
                break;
-       case FCME_GIDPN_DONE:
-               qla24xx_handle_gidpn_event(vha, ea);
-               break;
        case FCME_GNL_DONE:
                qla24xx_handle_gnl_done_event(vha, ea);
                break;
@@ -1650,6 +1674,36 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
        }
 }
 
+/*
+ * RSCN(s) came in for this fcport, but the RSCN(s) was not able
+ * to be consumed by the fcport
+ */
+void qla_rscn_replay(fc_port_t *fcport)
+{
+       struct event_arg ea;
+
+       switch (fcport->disc_state) {
+       case DSC_DELETE_PEND:
+               return;
+       default:
+               break;
+       }
+
+       if (fcport->scan_needed) {
+               memset(&ea, 0, sizeof(ea));
+               ea.event = FCME_RSCN;
+               ea.id = fcport->d_id;
+               ea.id.b.rsvd_1 = RSCN_PORT_ADDR;
+#if defined BIGSCAN & BIGSCAN > 0
+               qla2x00_fcport_event_handler(fcport->vha, &ea);
+#else
+               qla24xx_post_gpnid_work(fcport->vha, &ea.id);
+#endif
+       } else {
+               qla24xx_post_gnl_work(fcport->vha, fcport);
+       }
+}
+
 static void
 qla2x00_tmf_iocb_timeout(void *data)
 {
@@ -1905,9 +1959,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
                return;
        } else if (ea->sp->gen1 != fcport->rscn_gen) {
-               ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
-                   __func__, __LINE__, fcport->port_name);
-               qla24xx_post_gidpn_work(vha, fcport);
+               qla_rscn_replay(fcport);
                return;
        }
 
@@ -1996,8 +2048,6 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                            "%s %d %8phC NPortId %06x inuse with loopid 0x%x. post gidpn\n",
                            __func__, __LINE__, ea->fcport->port_name,
                            ea->fcport->d_id.b24, lid);
-                       qla2x00_clear_loop_id(ea->fcport);
-                       qla24xx_post_gidpn_work(vha, ea->fcport);
                } else {
                        ql_dbg(ql_dbg_disc, vha, 0x20ed,
                            "%s %d %8phC NPortId %06x inuse with loopid 0x%x. sched delete\n",
index b8b7415bc59d0abf2bbd5ef0c107382fb1993404..842456132e27044ff60345beeb94e1adb79f2726 100644 (file)
@@ -5032,9 +5032,6 @@ qla2x00_do_work(struct scsi_qla_host *vha)
                case QLA_EVT_AENFX:
                        qlafx00_process_aen(vha, e);
                        break;
-               case QLA_EVT_GIDPN:
-                       qla24xx_async_gidpn(vha, e->u.fcport.fcport);
-                       break;
                case QLA_EVT_GPNID:
                        qla24xx_async_gpnid(vha, &e->u.gpnid.id);
                        break;