From e23ef4f22db30a1e49c8b060e4ebc9dc9ca99c49 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Wed, 8 Oct 2025 14:55:43 +0800 Subject: [PATCH] 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 commit f966e02ae521 ("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: f966e02ae521 ("scsi: ufs: core: Fix runtime suspend error deadlock") Reported-by: Dan Carpenter Signed-off-by: Peter Wang Reviewed-by: Bart Van Assche Link: https://patch.msgid.link/20251008065651.1589614-2-peter.wang@mediatek.com Signed-off-by: Martin K. Petersen --- drivers/ufs/core/ufshcd.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 8339fec975b92..8f4e884892a90 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -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); -- 2.47.3