Blob Blame History Raw
From: Saurav Kashyap <skashyap@marvell.com>
Date: Tue, 8 Feb 2022 01:39:46 -0800
Subject: scsi: qla2xxx: Add qla2x00_async_done() for async routines
Patch-mainline: v5.18-rc1
Git-commit: 49b729f58e7a98a006a8a0c1dcca8a1a4f58d2a8
References: bsc#1195823

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>
Acked-by: Daniel Wagner <dwagner@suse.de>
---
 drivers/scsi/qla2xxx/qla_iocb.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2561,6 +2561,20 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mg
 	}
 }
 
+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)
 {
@@ -2574,7 +2588,8 @@ qla2x00_init_async_sp(srb_t *sp, unsigne
 		     void (*done)(struct srb *sp, int res))
 {
 	init_timer(&sp->u.iocb_cmd.timer);
-	sp->done = done;
+	sp->done = qla2x00_async_done;
+	sp->async_done = done;
 	sp->u.iocb_cmd.timer.data = (unsigned long)sp;
 	sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout;
 	sp->free = qla2x00_sp_free;