Skip to content

Commit

Permalink
scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing
Browse files Browse the repository at this point in the history
[ Upstream commit 9c40c36 ]

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: 7ebb336 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Quinn Tran authored and gregkh committed Aug 17, 2022
1 parent beb5bba commit bf890f1
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 37 deletions.
2 changes: 2 additions & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -3201,6 +3201,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;
Expand Down
32 changes: 29 additions & 3 deletions drivers/scsi/qla2xxx/qla_edif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -884,6 +896,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))
Expand Down
3 changes: 2 additions & 1 deletion drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,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.
Expand Down Expand Up @@ -722,7 +723,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 *);
Expand Down
118 changes: 86 additions & 32 deletions drivers/scsi/qla2xxx/qla_gs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3276,30 +3276,23 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
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;

ql_dbg(ql_dbg_disc, vha, 0x2133,
"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
Expand All @@ -3320,68 +3313,129 @@ 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 */
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
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;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/qla2xxx/qla_iocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit bf890f1

Please sign in to comment.