mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 14:41:22 -05:00
scsi: ufs: core: Fix error handler host_sem issue
Fix the issue where host_sem is not released due to a new return path in commitf966e02ae5("scsi: ufs: core: Fix runtime suspend error deadlock"). Check pm_op_in_progress before acquiring hba->host_sem to prevent deadlocks and ensure proper resource management during error handling. Add comment for use ufshcd_rpm_get_noresume() to safely perform link recovery without interfering with ongoing PM operations. Fixes:f966e02ae5("scsi: ufs: core: Fix runtime suspend error deadlock") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Peter Wang <peter.wang@mediatek.com> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Link: https://patch.msgid.link/20251008065651.1589614-2-peter.wang@mediatek.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
committed by
Martin K. Petersen
parent
a0b7780602
commit
e23ef4f22d
@@ -6673,6 +6673,20 @@ static void ufshcd_err_handler(struct work_struct *work)
|
||||
hba->saved_uic_err, hba->force_reset,
|
||||
ufshcd_is_link_broken(hba) ? "; link is broken" : "");
|
||||
|
||||
/*
|
||||
* Use ufshcd_rpm_get_noresume() here to safely perform link recovery
|
||||
* even if an error occurs during runtime suspend or runtime resume.
|
||||
* This avoids potential deadlocks that could happen if we tried to
|
||||
* resume the device while a PM operation is already in progress.
|
||||
*/
|
||||
ufshcd_rpm_get_noresume(hba);
|
||||
if (hba->pm_op_in_progress) {
|
||||
ufshcd_link_recovery(hba);
|
||||
ufshcd_rpm_put(hba);
|
||||
return;
|
||||
}
|
||||
ufshcd_rpm_put(hba);
|
||||
|
||||
down(&hba->host_sem);
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
if (ufshcd_err_handling_should_stop(hba)) {
|
||||
@@ -6684,14 +6698,6 @@ static void ufshcd_err_handler(struct work_struct *work)
|
||||
}
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
|
||||
ufshcd_rpm_get_noresume(hba);
|
||||
if (hba->pm_op_in_progress) {
|
||||
ufshcd_link_recovery(hba);
|
||||
ufshcd_rpm_put(hba);
|
||||
return;
|
||||
}
|
||||
ufshcd_rpm_put(hba);
|
||||
|
||||
ufshcd_err_handling_prepare(hba);
|
||||
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
|
||||
Reference in New Issue
Block a user