]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: qla2xxx: Do command completion on abort timeout
authorQuinn Tran <qutran@marvell.com>
Tue, 5 Nov 2019 15:06:51 +0000 (07:06 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Dec 2019 18:55:27 +0000 (19:55 +0100)
commit 71c80b75ce8f08c0978ce9a9816b81b5c3ce5e12 upstream.

On switch, fabric and mgt command timeout, driver send Abort to tell FW to
return the original command.  If abort is timeout, then return both Abort
and original command for cleanup.

Fixes: 219d27d7147e0 ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands")
Cc: stable@vger.kernel.org # 5.2
Link: https://lore.kernel.org/r/20191105150657.8092-3-hmadhani@marvell.com
Reviewed-by: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c

index 6ffa9877c28b46bbd371dd949835c06fae92bad3..19a919b85ca52321ef360a16e069afa5a9120b79 100644 (file)
@@ -604,6 +604,7 @@ typedef struct srb {
        const char *name;
        int iocbs;
        struct qla_qpair *qpair;
+       struct srb *cmd_sp;
        struct list_head elem;
        u32 gen1;       /* scratch */
        u32 gen2;       /* scratch */
index 1d041313ec522bc659a154120cbe071979957b1a..df6984ad57d85660bdbe08955ff9ef53781e14a0 100644 (file)
@@ -101,8 +101,22 @@ static void qla24xx_abort_iocb_timeout(void *data)
        u32 handle;
        unsigned long flags;
 
+       if (sp->cmd_sp)
+               ql_dbg(ql_dbg_async, sp->vha, 0x507c,
+                   "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n",
+                   sp->cmd_sp->handle, sp->cmd_sp->type,
+                   sp->handle, sp->type);
+       else
+               ql_dbg(ql_dbg_async, sp->vha, 0x507c,
+                   "Abort timeout 2 - hdl=%x, type=%x\n",
+                   sp->handle, sp->type);
+
        spin_lock_irqsave(qpair->qp_lock_ptr, flags);
        for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
+               if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
+                   sp->cmd_sp))
+                       qpair->req->outstanding_cmds[handle] = NULL;
+
                /* removing the abort */
                if (qpair->req->outstanding_cmds[handle] == sp) {
                        qpair->req->outstanding_cmds[handle] = NULL;
@@ -111,6 +125,9 @@ static void qla24xx_abort_iocb_timeout(void *data)
        }
        spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
 
+       if (sp->cmd_sp)
+               sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
+
        abt->u.abt.comp_status = CS_TIMEOUT;
        sp->done(sp, QLA_OS_TIMER_EXPIRED);
 }
@@ -142,6 +159,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
        sp->type = SRB_ABT_CMD;
        sp->name = "abort";
        sp->qpair = cmd_sp->qpair;
+       sp->cmd_sp = cmd_sp;
        if (wait)
                sp->flags = SRB_WAKEUP_ON_COMP;