[PATCH 1/2] scsi: mvsas: drain delayed work before unmapping MMIO in mvs_free()
From: Sangyun Kim
Date: Sat Apr 18 2026 - 09:30:26 EST
mvs_free() currently calls MVS_CHIP_DISP->chip_iounmap(mvi) before the
loop that cancels pending mwq->work_q delayed work items. If a
mvs_work_queue() callback starts executing between chip_iounmap() and
cancel_delayed_work_sync(), it dereferences the now-unmapped MMIO
region via MVS_CHIP_DISP->read_phy_ctl() and faults.
Move the cancel_delayed_work_sync() loop above chip_iounmap() so that
all pending and running callbacks have completed before the MMIO BARs
are torn down. scsi_host_put() is also deferred past the cancel loop
so that no callback can touch host state that has already been
released.
Signed-off-by: Sangyun Kim <sangyun.kim@xxxxxxxxx>
---
drivers/scsi/mvsas/mv_init.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 5abc17a2e261..0c9c62c25987 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -120,11 +120,11 @@ static void mvs_free(struct mvs_info *mvi)
dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE,
mvi->bulk_buffer1, mvi->bulk_buffer_dma1);
+ list_for_each_entry(mwq, &mvi->wq_list, entry)
+ cancel_delayed_work_sync(&mwq->work_q);
MVS_CHIP_DISP->chip_iounmap(mvi);
if (mvi->shost)
scsi_host_put(mvi->shost);
- list_for_each_entry(mwq, &mvi->wq_list, entry)
- cancel_delayed_work_sync(&mwq->work_q);
kfree(mvi->rsvd_tags);
kfree(mvi);
}
--
2.34.1