diff options
author | Saurav Kashyap <skashyap@marvell.com> | 2022-02-08 01:39:46 -0800 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2022-02-11 16:36:34 -0500 |
commit | 49b729f58e7a98a006a8a0c1dcca8a1a4f58d2a8 (patch) | |
tree | 88cae31e5b30ec7e615b6ed8028948b1b08429ed | |
parent | 62ed6622aaf0ba3c41cc6db6f901cbaa2a7378d1 (diff) | |
download | linux-49b729f58e7a98a006a8a0c1dcca8a1a4f58d2a8.tar.bz2 |
scsi: qla2xxx: Add qla2x00_async_done() for async routines
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>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 7dd82214d59f..5e3ee1f7b43c 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -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; |