]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: qla2xxx: Fix race condition between iocb timeout and initialisation
authorBen Hutchings <ben.hutchings@codethink.co.uk>
Tue, 20 Mar 2018 21:36:14 +0000 (21:36 +0000)
committerBrian Maly <brian.maly@oracle.com>
Tue, 30 Oct 2018 18:25:16 +0000 (14:25 -0400)
qla2x00_init_timer() calls add_timer() on the iocb timeout timer, which
means the timeout function pointer and any data that the function depends on
must be initialised beforehand.

Move this initialisation before each call to qla2x00_init_timer().  In some
cases qla2x00_init_timer() initialises a completion structure needed by the
timeout function, so move the call to add_timer() after that.

Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Acked-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit e74e7d95878d7993cf56c801d55d78f16ea58d1d)

Orabug: 28013813

Signed-off-by: Somasundaram Krishnasamy <somasundaram.krishnasamy@oracle.com>
Reviewed-by: Chuck Anderson <chuck.anderson@oracle.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
Conflicts:
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_mr.c

Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mr.c
drivers/scsi/qla2xxx/qla_target.c

index c9233211824d8db2437729d6910cb52d9701508f..f5a85b49e03d74c1745d08b6362008c0ee765d4d 100644 (file)
@@ -2949,6 +2949,7 @@ int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport)
        sp->gen1 = fcport->rscn_gen;
        sp->gen2 = fcport->login_gen;
 
+       sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        /* CT_IU preamble  */
@@ -2968,7 +2969,6 @@ int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport)
        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);
@@ -3109,6 +3109,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
        sp->gen1 = fcport->rscn_gen;
        sp->gen2 = fcport->login_gen;
 
+       sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        /* CT_IU preamble  */
@@ -3127,7 +3128,6 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
        sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE;
        sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id;
 
-       sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        sp->done = qla24xx_async_gpsc_sp_done;
 
        rval = qla2x00_start_sp(sp);
@@ -3411,6 +3411,7 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
        sp->name = sp_to_str(SPCN_GPNID);
        sp->u.iocb_cmd.u.ctarg.id = *id;
        sp->gen1 = 0;
+       sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
@@ -3459,7 +3460,6 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
        sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_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_gpnid_sp_done;
 
        rval = qla2x00_start_sp(sp);
index fd9e9343d5197f23e0a92b5103f5193f879cad52..e865c811c349306776fa380f776767681ac20bea 100644 (file)
@@ -184,10 +184,11 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
 
        sp->type = SRB_LOGIN_CMD;
        sp->name = sp_to_str(SPCN_LOGIN);
-       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        lio = &sp->u.iocb_cmd;
        lio->timeout = qla2x00_async_iocb_timeout;
+       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
        sp->done = qla2x00_async_login_sp_done;
        lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
        if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
@@ -242,10 +243,11 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
 
        sp->type = SRB_LOGOUT_CMD;
        sp->name = sp_to_str(SPCN_LOGOUT);
-       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        lio = &sp->u.iocb_cmd;
        lio->timeout = qla2x00_async_iocb_timeout;
+       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
        sp->done = qla2x00_async_logout_sp_done;
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS)
@@ -294,10 +296,11 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
 
        sp->type = SRB_ADISC_CMD;
        sp->name = sp_to_str(SPCN_ADISC);
-       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        lio = &sp->u.iocb_cmd;
        lio->timeout = qla2x00_async_iocb_timeout;
+       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
        sp->done = qla2x00_async_adisc_sp_done;
        if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
                lio->u.logio.flags |= SRB_LOGIN_RETRIED;
@@ -576,6 +579,8 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
        sp->gen1 = fcport->rscn_gen;
        sp->gen2 = fcport->login_gen;
 
+       mbx = &sp->u.iocb_cmd;
+       mbx->timeout = qla2x00_async_iocb_timeout;
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2);
 
        mb = sp->u.iocb_cmd.u.mbx.out_mb;
@@ -588,9 +593,6 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
        mb[8] = vha->gnl.size;
        mb[9] = vha->vp_idx;
 
-       mbx = &sp->u.iocb_cmd;
-       mbx->timeout = qla2x00_async_iocb_timeout;
-
        sp->done = qla24xx_async_gnl_sp_done;
 
        rval = qla2x00_start_sp(sp);
@@ -709,6 +711,9 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
        sp->name = sp_to_str(SPCN_GPDB);
        sp->gen1 = fcport->rscn_gen;
        sp->gen2 = fcport->login_gen;
+
+       mbx = &sp->u.iocb_cmd;
+       mbx->timeout = qla2x00_async_iocb_timeout;
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        mb = sp->u.iocb_cmd.u.mbx.out_mb;
@@ -721,8 +726,6 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
        mb[9] = vha->vp_idx;
        mb[10] = opt;
 
-       mbx = &sp->u.iocb_cmd;
-       mbx->timeout = qla2x00_async_iocb_timeout;
        mbx->u.mbx.in = (void *)pd;
        mbx->u.mbx.in_dma = pd_dma;
 
@@ -1184,13 +1187,15 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
        tm_iocb = &sp->u.iocb_cmd;
        sp->type = SRB_TM_CMD;
        sp->name = sp_to_str(SPCN_TMF);
+
+       tm_iocb->timeout = qla2x00_tmf_iocb_timeout;
+       init_completion(&tm_iocb->u.tmf.comp);
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
+
        tm_iocb->u.tmf.flags = flags;
        tm_iocb->u.tmf.lun = lun;
        tm_iocb->u.tmf.data = tag;
        sp->done = qla2x00_tmf_sp_done;
-       tm_iocb->timeout = qla2x00_tmf_iocb_timeout;
-       init_completion(&tm_iocb->u.tmf.comp);
 
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS)
@@ -1262,11 +1267,12 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp)
        abt_iocb = &sp->u.iocb_cmd;
        sp->type = SRB_ABT_CMD;
        sp->name = sp_to_str(SPCN_ABORT);
+       abt_iocb->timeout = qla24xx_abort_iocb_timeout;
+       init_completion(&abt_iocb->u.abt.comp);
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
+
        abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
        sp->done = qla24xx_abort_sp_done;
-       abt_iocb->timeout = qla24xx_abort_iocb_timeout;
-       init_completion(&abt_iocb->u.abt.comp);
 
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS)
index 66df6cec59da4059f064410536c48995635c80ee..571188942992c486424d96121a8fea124771207e 100644 (file)
@@ -284,12 +284,12 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
        sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
        sp->u.iocb_cmd.timer.data = (unsigned long)sp;
        sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout;
-       add_timer(&sp->u.iocb_cmd.timer);
        sp->free = qla2x00_sp_free;
        if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD))
                init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
        if (sp->type == SRB_ELS_DCMD)
                init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
+       add_timer(&sp->u.iocb_cmd.timer);
 }
 
 static inline int
index b8dcd33afb3e653a3acf1ba8dd5569163ef1e561..d11101aa60123119590b84fea62c35abd49e03de 100644 (file)
@@ -2639,8 +2639,8 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
        sp->type = SRB_ELS_DCMD;
        sp->name = sp_to_str(SPCN_ELS_DCMD);
        sp->fcport = fcport;
-       qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
        elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
+       qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
        sp->done = qla2x00_els_dcmd_sp_done;
        sp->free = qla2x00_els_dcmd_sp_free;
 
index 7934db629fb1a92dc6a8b21feb563eda23cbc689..6a1833eb7c07eab157896375abdb5a13f8664fd9 100644 (file)
@@ -5594,14 +5594,14 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
        sp->type = SRB_MB_IOCB;
        sp->name = mb_to_str(mcp->mb[0]);
 
-       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
-
-       memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
-
        c = &sp->u.iocb_cmd;
        c->timeout = qla2x00_async_iocb_timeout;
        init_completion(&c->u.mbx.comp);
 
+       qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+       memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
+
        sp->done = qla2x00_async_mb_sp_done;
 
        rval = qla2x00_start_sp(sp);
index be91550b8c72b6741540b954018fa7e15632fedb..6aa42762f98935e3bbff4415b0e0ca96f7126527 100644 (file)
@@ -1818,7 +1818,13 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
        if (!sp)
                goto done;
 
+       sp->type = SRB_FXIOCB_DCMD;
+       sp->name = sp_to_str(SPCN_FXDISC);
+
        fdisc = &sp->u.iocb_cmd;
+       fdisc->timeout = qla2x00_fxdisc_iocb_timeout;
+       qla2x00_init_timer(sp, FXDISC_TIMEOUT);
+
        switch (fx_type) {
        case FXDISC_GET_CONFIG_INFO:
        fdisc->u.fxiocb.flags =
@@ -1920,10 +1926,6 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
                        goto done_unmap_req;
        }
 
-       sp->type = SRB_FXIOCB_DCMD;
-       sp->name = sp_to_str(SPCN_FXDISC);
-       qla2x00_init_timer(sp, FXDISC_TIMEOUT);
-       fdisc->timeout = qla2x00_fxdisc_iocb_timeout;
        fdisc->u.fxiocb.req_func_type = cpu_to_le16(fx_type);
        sp->done = qla2x00_fxdisc_sp_done;
 
index 68282a00602619f296bb4eaa42fc61929b229b88..228c8cdf85e2df7c364828ec3da28dbd381e7ca3 100644 (file)
@@ -623,10 +623,10 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
        sp->type = type;
        sp->name = sp_to_str(SPCN_NACK);
 
+       sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2);
 
        sp->u.iocb_cmd.u.nack.ntfy = ntfy;
-       sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        sp->done = qla2x00_async_nack_sp_done;
 
        rval = qla2x00_start_sp(sp);