Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <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>

authored by

Peter Wang and committed by
Martin K. Petersen
e23ef4f2 a0b77806

+14 -8
+14 -8
drivers/ufs/core/ufshcd.c
··· 6673 6673 hba->saved_uic_err, hba->force_reset, 6674 6674 ufshcd_is_link_broken(hba) ? "; link is broken" : ""); 6675 6675 6676 + /* 6677 + * Use ufshcd_rpm_get_noresume() here to safely perform link recovery 6678 + * even if an error occurs during runtime suspend or runtime resume. 6679 + * This avoids potential deadlocks that could happen if we tried to 6680 + * resume the device while a PM operation is already in progress. 6681 + */ 6682 + ufshcd_rpm_get_noresume(hba); 6683 + if (hba->pm_op_in_progress) { 6684 + ufshcd_link_recovery(hba); 6685 + ufshcd_rpm_put(hba); 6686 + return; 6687 + } 6688 + ufshcd_rpm_put(hba); 6689 + 6676 6690 down(&hba->host_sem); 6677 6691 spin_lock_irqsave(hba->host->host_lock, flags); 6678 6692 if (ufshcd_err_handling_should_stop(hba)) { ··· 6697 6683 return; 6698 6684 } 6699 6685 spin_unlock_irqrestore(hba->host->host_lock, flags); 6700 - 6701 - ufshcd_rpm_get_noresume(hba); 6702 - if (hba->pm_op_in_progress) { 6703 - ufshcd_link_recovery(hba); 6704 - ufshcd_rpm_put(hba); 6705 - return; 6706 - } 6707 - ufshcd_rpm_put(hba); 6708 6686 6709 6687 ufshcd_err_handling_prepare(hba); 6710 6688