From 9a632cf08cf8aa40ff3c33fc6dc8925d081a92be Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Thu, 1 Aug 2019 15:56:10 -0400 Subject: [PATCH 110/124] [scsi] scsi: qla2xxx: Fix abort timeout race condition Message-id: <20190801155618.12650-111-hmadhani@redhat.com> Patchwork-id: 267890 O-Subject: [RHEL 7.8 e-stor PATCH 110/118] scsi: qla2xxx: Fix abort timeout race condition. Bugzilla: 1729270 RH-Acked-by: Jarod Wilson RH-Acked-by: Tony Camuso From: Quinn Tran Bugzilla 1729270 If an abort times out, the Abort IOCB completion and Abort timer can race against each other. This patch provides unique error code for timer path to allow proper cleanup. [mkp: typo] Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen (cherry picked from commit 0c6df59061b23c7a951836d23977be34e896d3da) Signed-off-by: Himanshu Madhani Signed-off-by: Jan Stancek --- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_init.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 4c82d210c95d..2ddf38c323ca 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -4661,6 +4661,7 @@ struct secure_flash_update_block_pk { #define QLA_SUSPENDED 0x106 #define QLA_BUSY 0x107 #define QLA_ALREADY_REGISTERED 0x109 +#define QLA_OS_TIMER_EXPIRED 0x10a #define NVRAM_DELAY() udelay(10) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index dc597073020f..d37704f64046 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1790,9 +1790,22 @@ qla24xx_abort_iocb_timeout(void *data) { srb_t *sp = data; struct srb_iocb *abt = &sp->u.iocb_cmd; + struct qla_qpair *qpair = sp->qpair; + u32 handle; + unsigned long flags; + + spin_lock_irqsave(qpair->qp_lock_ptr, flags); + for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) { + /* removing the abort */ + if (qpair->req->outstanding_cmds[handle] == sp) { + qpair->req->outstanding_cmds[handle] = NULL; + break; + } + } + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); abt->u.abt.comp_status = CS_TIMEOUT; - sp->done(sp, QLA_FUNCTION_TIMEOUT); + sp->done(sp, QLA_OS_TIMER_EXPIRED); } static void @@ -1801,7 +1814,8 @@ qla24xx_abort_sp_done(void *ptr, int res) srb_t *sp = ptr; struct srb_iocb *abt = &sp->u.iocb_cmd; - if (del_timer(&sp->u.iocb_cmd.timer)) { + if ((res == QLA_OS_TIMER_EXPIRED) || + del_timer(&sp->u.iocb_cmd.timer)) { if (sp->flags & SRB_WAKEUP_ON_COMP) complete(&abt->u.abt.comp); else -- 2.13.6