Hi all, On Mon, 10 Dec 2018 17:17:16 +1100 Stephen Rothwell wrote: > > I fixed it up (see below) and can carry the fix as necessary. This See below :-) Also I accidentally left the declaration of "status" in __qla2x00_abort_all_cmds(). -- Cheers, Stephen Rothwell diff --cc drivers/scsi/qla2xxx/qla_os.c index f92196ec5489,643cd7c0efc1..000000000000 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@@ -1742,6 -1746,41 +1742,49 @@@ qla2x00_loop_reset(scsi_qla_host_t *vha return QLA_SUCCESS; } + static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, + unsigned long *flags) + __releases(qp->qp_lock_ptr) + __acquires(qp->qp_lock_ptr) + { + scsi_qla_host_t *vha = qp->vha; + struct qla_hw_data *ha = vha->hw; + + if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS) { + if (!sp_get(sp)) { + /* got sp */ + spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); + qla_nvme_abort(ha, sp, res); + spin_lock_irqsave(qp->qp_lock_ptr, *flags); + } + } else if (GET_CMD_SP(sp) && !ha->flags.eeh_busy && + !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && + !qla2x00_isp_reg_stat(ha) && sp->type == SRB_SCSI_CMD) { + /* + * Don't abort commands in adapter during EEH recovery as it's + * not accessible/responding. + * + * Get a reference to the sp and drop the lock. The reference + * ensures this sp->done() call and not the call in + * qla2xxx_eh_abort() ends the SCSI cmd (with result 'res'). + */ + if (!sp_get(sp)) { ++ int status; ++ + spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); - qla2xxx_eh_abort(GET_CMD_SP(sp)); ++ status = qla2xxx_eh_abort(GET_CMD_SP(sp)); + spin_lock_irqsave(qp->qp_lock_ptr, *flags); ++ /* ++ * Get rid of extra reference causedby early ++ * exit from qla2xxx_eh_abort ++ */ ++ if (status == FAST_IO_FAIL) ++ atomic_dec(&sp->ref_count); + } + } + sp->done(sp, res); + } + static void __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) {