]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
scsi: qla2xxx: Add qla2x00_async_done() for async routines
authorSaurav Kashyap <skashyap@marvell.com>
Tue, 8 Feb 2022 09:39:46 +0000 (01:39 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2022 12:06:53 +0000 (14:06 +0200)
commit 49b729f58e7a98a006a8a0c1dcca8a1a4f58d2a8 upstream.

This done routine will delete the timer and check for its return value and
decrease the reference count accordingly. This prevents boot hangs reported
after commit 31e6cdbe0eae ("scsi: qla2xxx: Implement ref count for SRB")
was merged.

Link: https://lore.kernel.org/r/20220208093946.4471-1-njavali@marvell.com
Fixes: 31e6cdbe0eae ("scsi: qla2xxx: Implement ref count for SRB")
Reported-by: Ewan Milne <emilne@redhat.com>
Tested-by: Ewan D. Milne <emilne@redhat.com>
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
Signed-off-by: Nilesh Javali <njavali@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_iocb.c

index 85cccc7b9f83089d84b50c415c0f4aac1aaee0a5..e0fe9ddb4bd2cea4b15b7ffc1c4d55551ddd4887 100644 (file)
@@ -2560,6 +2560,20 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
        }
 }
 
+static void
+qla2x00_async_done(struct srb *sp, int res)
+{
+       if (del_timer(&sp->u.iocb_cmd.timer)) {
+               /*
+                * Successfully cancelled the timeout handler
+                * ref: TMR
+                */
+               if (kref_put(&sp->cmd_kref, qla2x00_sp_release))
+                       return;
+       }
+       sp->async_done(sp, res);
+}
+
 void
 qla2x00_sp_release(struct kref *kref)
 {
@@ -2573,7 +2587,8 @@ qla2x00_init_async_sp(srb_t *sp, unsigned long tmo,
                     void (*done)(struct srb *sp, int res))
 {
        timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0);
-       sp->done = done;
+       sp->done = qla2x00_async_done;
+       sp->async_done = done;
        sp->free = qla2x00_sp_free;
        sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
        sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;