From acba3a9a6d19558b7f4f45dbe042154a7cd757c3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 14 Apr 2019 16:20:11 +0000 Subject: [PATCH 1/2] qla2x00t-32gbit: Revert r8226 Since r8226 is not a full solution and since it relies on wait_event_lock_irq_timeout(), revert it. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8237 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 2 +- qla2x00t-32gbit/qla_os.c | 87 ++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 48 deletions(-) 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); From 86c69ab494641db66941ab88f5485332b9cc6f9a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 14 Apr 2019 16:25:46 +0000 Subject: [PATCH 2/2] scst/include/backport.h: Remove the wait_event_lock_irq_timeout() backport Due to the previous patch this backport is no longer needed. Note: the wait_event_lock_irq_timeout() needs more work. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8238 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/backport.h | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/scst/include/backport.h b/scst/include/backport.h index 61051f5d3..7d6c51297 100644 --- a/scst/include/backport.h +++ b/scst/include/backport.h @@ -1544,47 +1544,6 @@ static inline void *vzalloc(unsigned long size) } #endif -/* */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) -/* - * See also commit 35a2af94c7ce ("sched/wait: Make the __wait_event*() - * interface more friendly") # v3.13. - */ -#define ___wait_cond_timeout_backport(condition)\ -({ \ - bool __cond = (condition); \ - if (__cond && !__ret) \ - __ret = 1; \ - __cond || !__ret; \ -}) -#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) -#define ___wait_cond_timeout_backport ___wait_cond_timeout -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) -/* - * See also commit 25ab0bc334b4 ("scsi: sched/wait: Add - * wait_event_lock_irq_timeout for TASK_UNINTERRUPTIBLE usage") # v4.20. - */ -#define __wait_event_lock_irq_timeout(wq_head, condition, lock, timeout, state)\ - ___wait_event(wq_head, ___wait_cond_timeout_backport(condition),\ - state, 0, timeout, \ - spin_unlock_irq(&lock); \ - __ret = schedule_timeout(__ret); \ - spin_lock_irq(&lock)); - -#define wait_event_lock_irq_timeout(wq_head, condition, lock, timeout) \ -({ \ - long __ret = timeout; \ - if (!___wait_cond_timeout_backport(condition)) \ - __ret = __wait_event_lock_irq_timeout( \ - wq_head, condition, lock, timeout,\ - TASK_UNINTERRUPTIBLE); \ - __ret; \ -}) -#endif - /* */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)