There might be a racing issue between UFS shutdown and runtime resume flow described as below,
Thread #1: In UFS shutdown flow with ufshcd_shutdown() is running. Thread #2: In UFS runtime-resume flow which invokes ufshcd_runtime_resume() because UFS was in runtime-suspended state while an I/O request was issued. In this scenario, racing may happen and possibly lead to system hang if Thread #2 accesses UFS host's register map after host's resource, like power or clocks, are disabled by Thread #1. To avoid this racing, use PM public function pm_runtime_get_sync() in shutdown flow instead of internal function ufshcd_runtime_resume() for consolidated control of RPM status. One concern is that pm_runtime_get_sync() may be better paired with pm_runtime_put_sync(), however shutdown could be one-way path thus the pairing is not required. Signed-off-by: Stanley Chu <stanley....@mediatek.com> Signed-off-by: Peter Wang <peter.w...@mediatek.com> --- drivers/scsi/ufs/ufshcd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a208589426b1..cce7303f8653 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8095,11 +8095,8 @@ int ufshcd_shutdown(struct ufs_hba *hba) if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba)) goto out; - if (pm_runtime_suspended(hba->dev)) { - ret = ufshcd_runtime_resume(hba); - if (ret) - goto out; - } + if (pm_runtime_get_sync(hba->dev) < 0) + goto out; ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM); out: -- 2.18.0