On Tue, 2019-11-05 at 07:06 -0800, Himanshu Madhani wrote: > From: Quinn Tran <qutran@xxxxxxxxxxx> > > when GPSC/GPDB switch command fails, driver just returns > without doing a proper cleanup. This patch fixes this memory > leak by calling sp->free() in the error path. > > Signed-off-by: Quinn Tran <qutran@xxxxxxxxxxx> > Signed-off-by: Himanshu Madhani <hmadhani@xxxxxxxxxxx> > --- > drivers/scsi/qla2xxx/qla_gs.c | 2 +- > drivers/scsi/qla2xxx/qla_init.c | 11 +++++------ > drivers/scsi/qla2xxx/qla_mbx.c | 4 ---- > drivers/scsi/qla2xxx/qla_mid.c | 11 ++++------- > drivers/scsi/qla2xxx/qla_os.c | 7 ++++++- > 5 files changed, 16 insertions(+), 19 deletions(-) > > diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c > index 7a00272ca380..67230688b05e 100644 > --- a/drivers/scsi/qla2xxx/qla_gs.c > +++ b/drivers/scsi/qla2xxx/qla_gs.c > @@ -3010,7 +3010,7 @@ static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res) > fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); > > if (res == QLA_FUNCTION_TIMEOUT) > - return; > + goto done; > > if (res == (DID_ERROR << 16)) { > /* entry status error */ > diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c > index 7fdbe041cc19..bddb26baedd2 100644 > --- a/drivers/scsi/qla2xxx/qla_init.c > +++ b/drivers/scsi/qla2xxx/qla_init.c > @@ -1151,19 +1151,18 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) > "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n", > sp->name, res, fcport->port_name, mb[1], mb[2]); > > - if (res == QLA_FUNCTION_TIMEOUT) { > - dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, > - sp->u.iocb_cmd.u.mbx.in_dma); > - return; > - } > - > fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); > + > + if (res == QLA_FUNCTION_TIMEOUT) > + goto done; > + > memset(&ea, 0, sizeof(ea)); > ea.fcport = fcport; > ea.sp = sp; > > qla24xx_handle_gpdb_event(vha, &ea); > > +done: > dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, > sp->u.iocb_cmd.u.mbx.in_dma); > > diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c > index 04175c91af0e..0cf94f05f008 100644 > --- a/drivers/scsi/qla2xxx/qla_mbx.c > +++ b/drivers/scsi/qla2xxx/qla_mbx.c > @@ -6288,17 +6288,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) > case QLA_SUCCESS: > ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n", > __func__, sp->name); > - sp->free(sp); > break; > default: > ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n", > __func__, sp->name, rval); > - sp->free(sp); > break; > } > > - return rval; > - > done_free_sp: > sp->free(sp); > done: > diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c > index 6afad68e5ba2..bd62c4595b73 100644 > --- a/drivers/scsi/qla2xxx/qla_mid.c > +++ b/drivers/scsi/qla2xxx/qla_mid.c > @@ -944,7 +944,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) > > sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL); > if (!sp) > - goto done; > + return rval; > > sp->type = SRB_CTRL_VP; > sp->name = "ctrl_vp"; > @@ -960,7 +960,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) > ql_dbg(ql_dbg_async, vha, 0xffff, > "%s: %s Failed submission. %x.\n", > __func__, sp->name, rval); > - goto done_free_sp; > + goto done; > } > > ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", > @@ -978,16 +978,13 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) > case QLA_SUCCESS: > ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n", > __func__, sp->name); > - goto done_free_sp; > + break; > default: > ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n", > __func__, sp->name, rval); > - goto done_free_sp; > + break; > } > done: > - return rval; > - > -done_free_sp: > sp->free(sp); > return rval; > } > diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c > index 588e0d27f151..2e7a4a2d6c5a 100644 > --- a/drivers/scsi/qla2xxx/qla_os.c > +++ b/drivers/scsi/qla2xxx/qla_os.c > @@ -996,7 +996,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, > ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078, > "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd); > if (rval == QLA_INTERFACE_ERROR) > - goto qc24_fail_command; > + goto qc24_free_sp_fail_command; > goto qc24_host_busy_free_sp; > } > > @@ -1008,6 +1008,11 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, > qc24_target_busy: > return SCSI_MLQUEUE_TARGET_BUSY; > > +qc24_free_sp_fail_command: > + sp->free(sp); > + CMD_SP(cmd) = NULL; > + qla2xxx_rel_qpair_sp(sp->qpair, sp); > + > qc24_fail_command: > cmd->scsi_done(cmd); > Reviewed-by: Ewan D. Milne <emilne@xxxxxxxxxx>