Skip to content

Commit

Permalink
scsi: qla2xxx: Prevent command send on chip reset
Browse files Browse the repository at this point in the history
commit 4895009 upstream.

Currently IOCBs are allowed to push through while chip reset could be in
progress. During chip reset the outstanding_cmds array is cleared
twice. Once when any command on this array is returned as failed and
secondly when the array is initialize to zero. If a command is inserted on
to the array between these intervals, then the command will be lost.  Check
for chip reset before sending IOCB.

Cc: stable@vger.kernel.org
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://lore.kernel.org/r/20240227164127.36465-2-njavali@marvell.com
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Quinn Tran authored and gregkh committed Apr 3, 2024
1 parent bc2b57b commit 6c6bf6c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
8 changes: 6 additions & 2 deletions drivers/scsi/qla2xxx/qla_init.c
Expand Up @@ -1193,8 +1193,12 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
return rval;

done_free_sp:
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
/*
* use qla24xx_async_gnl_sp_done to purge all pending gnl request.
* kref_put is call behind the scene.
*/
sp->u.iocb_cmd.u.mbx.in_mb[0] = MBS_COMMAND_ERROR;
qla24xx_async_gnl_sp_done(sp, QLA_COMMAND_ERROR);
fcport->flags &= ~(FCF_ASYNC_SENT);
done:
fcport->flags &= ~(FCF_ASYNC_ACTIVE);
Expand Down
33 changes: 31 additions & 2 deletions drivers/scsi/qla2xxx/qla_iocb.c
Expand Up @@ -2587,6 +2587,33 @@ void
qla2x00_sp_release(struct kref *kref)
{
struct srb *sp = container_of(kref, struct srb, cmd_kref);
struct scsi_qla_host *vha = sp->vha;

switch (sp->type) {
case SRB_CT_PTHRU_CMD:
/* GPSC & GFPNID use fcport->ct_desc.ct_sns for both req & rsp */
if (sp->u.iocb_cmd.u.ctarg.req &&
(!sp->fcport ||
sp->u.iocb_cmd.u.ctarg.req != sp->fcport->ct_desc.ct_sns)) {
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 &&
(!sp->fcport ||
sp->u.iocb_cmd.u.ctarg.rsp != sp->fcport->ct_desc.ct_sns)) {
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;
}
break;
default:
break;
}

sp->free(sp);
}
Expand Down Expand Up @@ -2692,7 +2719,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
*/
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp) {
kfree(fcport);
qla2x00_free_fcport(fcport);
ql_log(ql_log_info, vha, 0x70e6,
"SRB allocation failed\n");
return -ENOMEM;
Expand Down Expand Up @@ -2747,6 +2774,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
if (rval != QLA_SUCCESS) {
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
qla2x00_free_fcport(fcport);
return QLA_FUNCTION_FAILED;
}

Expand All @@ -2756,6 +2784,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
fcport->d_id.b.area, fcport->d_id.b.al_pa);

wait_for_completion(&elsio->u.els_logo.comp);
qla2x00_free_fcport(fcport);

/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
Expand Down Expand Up @@ -3918,7 +3947,7 @@ qla2x00_start_sp(srb_t *sp)
return -EAGAIN;
}

pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
pkt = qla2x00_alloc_iocbs_ready(sp->qpair, sp);
if (!pkt) {
rval = -EAGAIN;
ql_log(ql_log_warn, vha, 0x700c,
Expand Down

0 comments on commit 6c6bf6c

Please sign in to comment.