diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 037674116..78a57ec98 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -560,7 +560,6 @@ typedef struct srb { int rc; int retry_count; struct completion comp; - wait_queue_head_t *cwaitq; union { struct srb_iocb iocb_cmd; #ifndef NEW_LIBFC_API @@ -4814,4 +4813,5 @@ struct sff_8247_a0 { #include "qla_gbl.h" #include "qla_dbg.h" #include "qla_inline.h" + #endif diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 3bb68d59c..22f76f1a4 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -766,7 +766,7 @@ qla2x00_sp_free_dma(void *ptr) } if (!ctx) - return; + goto end; if (sp->flags & SRB_CRC_CTX_DSD_VALID) { /* List assured to be having elements */ @@ -791,6 +791,12 @@ qla2x00_sp_free_dma(void *ptr) ha->gbl_dsd_avail += ctx1->dsd_use_cnt; mempool_free(ctx1, ha->ctx_mempool); } + +end: + if (sp->type != SRB_NVME_CMD && sp->type != SRB_NVME_LS) { + CMD_SP(cmd) = NULL; + qla2x00_rel_sp(sp); + } } void @@ -798,7 +804,6 @@ qla2x00_sp_compl(void *ptr, int res) { srb_t *sp = ptr; struct scsi_cmnd *cmd = GET_CMD_SP(sp); - wait_queue_head_t *cwaitq = sp->cwaitq; if (WARN_ON(atomic_read(&sp->ref_count) == 0)) return; @@ -808,11 +813,7 @@ qla2x00_sp_compl(void *ptr, int res) sp->free(sp); cmd->result = res; - CMD_SP(cmd) = NULL; cmd->scsi_done(cmd); - if (cwaitq) - wake_up(cwaitq); - qla2x00_rel_sp(sp); } void @@ -835,7 +836,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr) } if (!ctx) - return; + goto end; if (sp->flags & SRB_CRC_CTX_DSD_VALID) { /* List assured to be having elements */ @@ -895,6 +896,10 @@ qla2xxx_qpair_sp_free_dma(void *ptr) } sp->flags &= ~SRB_DIF_BUNDL_DMA_VALID; } + +end: + CMD_SP(cmd) = NULL; + qla2xxx_rel_qpair_sp(sp->qpair, sp); } void @@ -902,7 +907,8 @@ qla2xxx_qpair_sp_compl(void *ptr, int res) { srb_t *sp = ptr; struct scsi_cmnd *cmd = GET_CMD_SP(sp); - wait_queue_head_t *cwaitq = sp->cwaitq; + + cmd->result = res; if (WARN_ON(atomic_read(&sp->ref_count) == 0)) return; @@ -911,12 +917,7 @@ qla2xxx_qpair_sp_compl(void *ptr, int res) return; sp->free(sp); - cmd->result = res; - CMD_SP(cmd) = NULL; cmd->scsi_done(cmd); - if (cwaitq) - wake_up(cwaitq); - qla2xxx_rel_qpair_sp(sp->qpair, sp); } #if defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 6 && RHEL_MINOR -0 >= 2 @@ -1428,6 +1429,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) vha->host_no, id, lun, sp, cmd, sp->handle); /* Get a reference to the sp and drop the lock.*/ + rval = ha->isp_ops->abort_command(sp); if (rval) { if (rval == QLA_FUNCTION_PARAMETER_ERROR) @@ -1444,46 +1446,37 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) } spin_lock_irqsave(qpair->qp_lock_ptr, flags); + /* + * Clear the slot in the oustanding_cmds array if we can't find the + * command to reclaim the resources. + */ + if (rval == QLA_FUNCTION_PARAMETER_ERROR) + vha->req->outstanding_cmds[sp->handle] = NULL; /* - * Releasing of the SRB and associated command resources - * is managed through ref_count. - * Whether we need to wait for the abort completion or complete - * the abort handler should be based on the ref_count. + * sp->done will do ref_count-- + * sp_get() took an extra count above */ - if (atomic_read(&sp->ref_count) > 1) { - /* - * The command is not yet completed. We need to wait for either - * command completion or abort completion. - */ - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(eh_waitq); - uint32_t ratov = ha->r_a_tov/10; + sp->done(sp, DID_RESET << 16); - /* Go ahead and release the extra ref_count obtained earlier */ - sp->done(sp, DID_RESET << 16); - sp->cwaitq = &eh_waitq; + /* Did the command return during mailbox execution? */ + if (ret == FAILED && !CMD_SP(cmd)) + ret = SUCCESS; + + if (!CMD_SP(cmd)) + wait = 0; - if (!wait_event_lock_irq_timeout(eh_waitq, - CMD_SP(cmd) == NULL, *qpair->qp_lock_ptr, - msecs_to_jiffies(4 * ratov * 1000))) { - /* - * The abort got dropped, LOGO will be sent and the - * original command will be completed with CS_TIMEOUT - * completion - */ - ql_dbg(ql_dbg_taskm, vha, 0xffff, - "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", - __func__, ha->r_a_tov); - sp->cwaitq = NULL; - ret = FAILED; - goto end; - } - } else { - /* Command completed while processing the abort */ - sp->done(sp, DID_RESET << 16); - } -end: spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + + /* Wait for the command to be returned. */ + if (wait) { + if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x8006, + "Abort handler timed out cmd=%p.\n", cmd); + ret = FAILED; + } + } + ql_log(ql_log_info, vha, 0x801c, "Abort command issued nexus=%ld:%d:%llu -- %d %x.\n", vha->host_no, id, lun, wait, ret);