scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing
authorQuinn Tran <qutran@marvell.com>
Tue, 7 Jun 2022 04:46:17 +0000 (21:46 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 8 Jun 2022 01:50:09 +0000 (21:50 -0400)
This patch uses GFFID switch command to scan whether remote device is
Target or Initiator mode.  Based on that info, driver will not pass up
Initiator info to authentication application. This helps reduce unnecessary
stress for authentication application to deal with unused connections.

Link: https://lore.kernel.org/r/20220607044627.19563-2-njavali@marvell.com
Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_edif.c
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_iocb.c

index e8f69c486be105a30c6cb2c27a192aed9862a61a..510fbeb042561837f17a89611dce103d51d69a91 100644 (file)
@@ -3204,6 +3204,8 @@ struct ct_sns_rsp {
 #define GFF_NVME_OFFSET                23 /* type = 28h */
                struct {
                        uint8_t fc4_features[128];
+#define FC4_FF_TARGET    BIT_0
+#define FC4_FF_INITIATOR BIT_1
                } gff_id;
                struct {
                        uint8_t reserved;
index cb8145a9ac09aafd3dbab2bae56c70712eef7c61..e789f59395ce4cc02aad5d0aa7aef2375bd08018 100644 (file)
@@ -517,16 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
                        if (atomic_read(&vha->loop_state) == LOOP_DOWN)
                                break;
 
-                       fcport->edif.app_started = 1;
                        fcport->login_retry = vha->hw->login_retry_count;
 
-                       /* no activity */
                        fcport->edif.app_stop = 0;
+                       fcport->edif.app_sess_online = 0;
+                       fcport->edif.app_started = 1;
+
+                       if (fcport->scan_state != QLA_FCPORT_FOUND)
+                               continue;
+
+                       if (fcport->port_type == FCT_UNKNOWN &&
+                           !fcport->fc4_features)
+                               rval = qla24xx_async_gffid(vha, fcport, true);
+
+                       if (!rval && !(fcport->fc4_features & FC4_FF_TARGET ||
+                           fcport->port_type & (FCT_TARGET|FCT_NVME_TARGET)))
+                               continue;
+
+                       rval = 0;
 
                        ql_dbg(ql_dbg_edif, vha, 0x911e,
                               "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
                               __func__, fcport->port_name);
-                       fcport->edif.app_sess_online = 0;
                        qlt_schedule_sess_for_deletion(fcport);
                        qla_edif_sa_ctl_init(vha, fcport);
                }
@@ -883,6 +895,20 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
                        app_reply->ports[pcnt].rekey_count =
                                fcport->edif.rekey_cnt;
 
+                       if (fcport->scan_state != QLA_FCPORT_FOUND)
+                               continue;
+
+                       if (fcport->port_type == FCT_UNKNOWN && !fcport->fc4_features)
+                               rval = qla24xx_async_gffid(vha, fcport, true);
+
+                       if (!rval &&
+                           !(fcport->fc4_features & FC4_FF_TARGET ||
+                             fcport->port_type &
+                             (FCT_TARGET | FCT_NVME_TARGET)))
+                               continue;
+
+                       rval = 0;
+
                        app_reply->ports[pcnt].remote_type =
                                VND_CMD_RTYPE_UNKNOWN;
                        if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
index dac27b5ff0ac7ae19f5cc26fe35a724de9f6270f..84b44454c23104ad4f4723b7a331701fe42f771e 100644 (file)
@@ -335,6 +335,7 @@ extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
 extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
        struct qla_work_evt *e);
 void qla2x00_sp_release(struct kref *kref);
+void qla2x00_els_dcmd2_iocb_timeout(void *data);
 
 /*
  * Global Function Prototypes in qla_mbx.c source file.
@@ -727,7 +728,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
 void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
 int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
 void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
+int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool);
 int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *);
 void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
 void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
index e811de2f6a25faf8767c34e02b08f9f5a34f0489..350d7c22ac798ea57438ca3bdfdda403b33cd7e0 100644 (file)
@@ -3280,19 +3280,12 @@ done:
        return rval;
 }
 
-void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
-{
-       fc_port_t *fcport = ea->fcport;
-
-       qla24xx_post_gnl_work(vha, fcport);
-}
 
 void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
 {
        struct scsi_qla_host *vha = sp->vha;
        fc_port_t *fcport = sp->fcport;
        struct ct_sns_rsp *ct_rsp;
-       struct event_arg ea;
        uint8_t fc4_scsi_feat;
        uint8_t fc4_nvme_feat;
 
@@ -3300,10 +3293,10 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
               "Async done-%s res %x ID %x. %8phC\n",
               sp->name, res, fcport->d_id.b24, fcport->port_name);
 
-       fcport->flags &= ~FCF_ASYNC_SENT;
-       ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
+       ct_rsp = sp->u.iocb_cmd.u.ctarg.rsp;
        fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
        fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
+       sp->rc = res;
 
        /*
         * FC-GS-7, 5.2.3.12 FC-4 Features - format
@@ -3324,24 +3317,42 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
                }
        }
 
-       memset(&ea, 0, sizeof(ea));
-       ea.sp = sp;
-       ea.fcport = sp->fcport;
-       ea.rc = res;
+       if (sp->flags & SRB_WAKEUP_ON_COMP) {
+               complete(sp->comp);
+       } else  {
+               if (sp->u.iocb_cmd.u.ctarg.req) {
+                       dma_free_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.req_allocated_size,
+                               sp->u.iocb_cmd.u.ctarg.req,
+                               sp->u.iocb_cmd.u.ctarg.req_dma);
+                       sp->u.iocb_cmd.u.ctarg.req = NULL;
+               }
 
-       qla24xx_handle_gffid_event(vha, &ea);
-       /* ref: INIT */
-       kref_put(&sp->cmd_kref, qla2x00_sp_release);
+               if (sp->u.iocb_cmd.u.ctarg.rsp) {
+                       dma_free_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+                               sp->u.iocb_cmd.u.ctarg.rsp,
+                               sp->u.iocb_cmd.u.ctarg.rsp_dma);
+                       sp->u.iocb_cmd.u.ctarg.rsp = NULL;
+               }
+
+               /* ref: INIT */
+               kref_put(&sp->cmd_kref, qla2x00_sp_release);
+               /* we should not be here */
+               dump_stack();
+       }
 }
 
 /* Get FC4 Feature with Nport ID. */
-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
+int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
 {
        int rval = QLA_FUNCTION_FAILED;
        struct ct_sns_req       *ct_req;
        srb_t *sp;
+       DECLARE_COMPLETION_ONSTACK(comp);
 
-       if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
+       /* this routine does not have handling for no wait */
+       if (!vha->flags.online || !wait)
                return rval;
 
        /* ref: INIT */
@@ -3349,43 +3360,86 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
        if (!sp)
                return rval;
 
-       fcport->flags |= FCF_ASYNC_SENT;
        sp->type = SRB_CT_PTHRU_CMD;
        sp->name = "gffid";
        sp->gen1 = fcport->rscn_gen;
        sp->gen2 = fcport->login_gen;
        qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
                              qla24xx_async_gffid_sp_done);
+       sp->comp = &comp;
+       sp->u.iocb_cmd.timeout = qla2x00_els_dcmd2_iocb_timeout;
+
+       if (wait)
+               sp->flags = SRB_WAKEUP_ON_COMP;
+
+       sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
+       sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.req_allocated_size,
+                               &sp->u.iocb_cmd.u.ctarg.req_dma,
+           GFP_KERNEL);
+       if (!sp->u.iocb_cmd.u.ctarg.req) {
+               ql_log(ql_log_warn, vha, 0xd041,
+                      "%s: Failed to allocate ct_sns request.\n",
+                      __func__);
+               goto done_free_sp;
+       }
+
+       sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
+       sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
+                               sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+                               &sp->u.iocb_cmd.u.ctarg.rsp_dma,
+           GFP_KERNEL);
+       if (!sp->u.iocb_cmd.u.ctarg.req) {
+               ql_log(ql_log_warn, vha, 0xd041,
+                      "%s: Failed to allocate ct_sns request.\n",
+                      __func__);
+               goto done_free_sp;
+       }
 
        /* CT_IU preamble  */
-       ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
-           GFF_ID_RSP_SIZE);
+       ct_req = qla2x00_prep_ct_req(sp->u.iocb_cmd.u.ctarg.req, GFF_ID_CMD, GFF_ID_RSP_SIZE);
 
        ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
        ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
        ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
 
-       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 = GFF_ID_REQ_SIZE;
        sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
        sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
 
-       ql_dbg(ql_dbg_disc, vha, 0x2132,
-           "Async-%s hdl=%x  %8phC.\n", sp->name,
-           sp->handle, fcport->port_name);
-
        rval = qla2x00_start_sp(sp);
-       if (rval != QLA_SUCCESS)
+
+       if (rval != QLA_SUCCESS) {
+               rval = QLA_FUNCTION_FAILED;
                goto done_free_sp;
+       } else {
+               ql_dbg(ql_dbg_disc, vha, 0x3074,
+                      "Async-%s hdl=%x portid %06x\n",
+                      sp->name, sp->handle, fcport->d_id.b24);
+       }
+
+       wait_for_completion(sp->comp);
+       rval = sp->rc;
 
-       return rval;
 done_free_sp:
+       if (sp->u.iocb_cmd.u.ctarg.req) {
+               dma_free_coherent(&vha->hw->pdev->dev,
+                                 sp->u.iocb_cmd.u.ctarg.req_allocated_size,
+                                 sp->u.iocb_cmd.u.ctarg.req,
+                                 sp->u.iocb_cmd.u.ctarg.req_dma);
+               sp->u.iocb_cmd.u.ctarg.req = NULL;
+       }
+
+       if (sp->u.iocb_cmd.u.ctarg.rsp) {
+               dma_free_coherent(&vha->hw->pdev->dev,
+                                 sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+                                 sp->u.iocb_cmd.u.ctarg.rsp,
+                                 sp->u.iocb_cmd.u.ctarg.rsp_dma);
+               sp->u.iocb_cmd.u.ctarg.rsp = NULL;
+       }
+
        /* ref: INIT */
        kref_put(&sp->cmd_kref, qla2x00_sp_release);
-       fcport->flags &= ~FCF_ASYNC_SENT;
        return rval;
 }
 
index e0fe9ddb4bd2cea4b15b7ffc1c4d55551ddd4887..46c879923da1848a53b40d1eb959c87b4d964ab8 100644 (file)
@@ -2819,7 +2819,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
        sp->vha->qla_stats.control_requests++;
 }
 
-static void
+void
 qla2x00_els_dcmd2_iocb_timeout(void *data)
 {
        srb_t *sp = data;