mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
FROMLIST: scsi: ufs: Fix deadlocks between power management and error handler
The following deadlocks have been observed on multiple test setups:
* ufshcd_wl_suspend() is waiting for blk_execute_rq() to complete while it
holds host_sem.
* ufshcd_eh_host_reset_handler() invokes ufshcd_err_handler() and the
latter function tries to obtain host_sem.
This is a deadlock because blk_execute_rq() can't execute SCSI commands
while the host is in the SHOST_RECOVERY state and because the error
handler cannot make progress either.
* ufshcd_wl_runtime_resume() is waiting for blk_execute_rq() to finish
while it holds host_sem.
* ufshcd_eh_host_reset_handler() invokes ufshcd_err_handler() and the
latter function calls pm_runtime_resume().
This is a deadlock because of the same reason as the previous scenario.
Fix both deadlocks by not obtaining host_sem from the power management
code paths. Removing the host_sem locking from the power management code
is safe because the ufshcd_err_handler() is already serialized against
SCSI command execution.
Cc: dh0421.hwang@samsung.com
Cc: Asutosh Das <asutoshd@codeaurora.org>
Fixes: b294ff3e34 ("scsi: ufs: core: Enable power management for wlun")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Bug: 240498410
Bug: 246990788
Bug: 247073231
Bug: 247081382
Bug: 247082093
Link: https://lore.kernel.org/linux-scsi/
Signed-off-by: Bart Van Assche <bvanassche@google.com>
Change-Id: Ifb9b429ba89ff6d8a133d96a172eaefc09d85955
This commit is contained in:
committed by
Bart Van Assche
parent
32934b542c
commit
f68d040c31
@@ -9337,16 +9337,13 @@ static int ufshcd_wl_suspend(struct device *dev)
|
||||
ktime_t start = ktime_get();
|
||||
|
||||
hba = shost_priv(sdev->host);
|
||||
down(&hba->host_sem);
|
||||
|
||||
if (pm_runtime_suspended(dev))
|
||||
goto out;
|
||||
|
||||
ret = __ufshcd_wl_suspend(hba, UFS_SYSTEM_PM);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
dev_err(&sdev->sdev_gendev, "%s failed: %d\n", __func__, ret);
|
||||
up(&hba->host_sem);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!ret)
|
||||
@@ -9379,7 +9376,6 @@ out:
|
||||
hba->curr_dev_pwr_mode, hba->uic_link_state);
|
||||
if (!ret)
|
||||
hba->is_sys_suspended = false;
|
||||
up(&hba->host_sem);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user