diff mbox series

[v1] ufs: core: fix runtime pm with uic error(NON_FATAL) hang

Message ID 20230830131403.14193-1-peter.wang@mediatek.com
State New
Headers show
Series [v1] ufs: core: fix runtime pm with uic error(NON_FATAL) hang | expand

Commit Message

Peter Wang (王信友) Aug. 30, 2023, 1:14 p.m. UTC
From: Peter Wang <peter.wang@mediatek.com>

When uic error (NON_FATAL) happen in runtime pm flow, ufshcd_err_handler
stuck in ufshcd_rpm_get_sync, but runtime pm(suspend or resume) stuck in
send SSU(sleep or active) which always get SCSI_MLQUEUE_HOST_BUSY.

This patch try to solve this deadlock:
1. Return error to break runtime suspend let err handler going, same as
   UFSHCD_STATE_EH_SCHEDULED_FATAL do.
2. Try do recovery if SSU(active) fail when resume, prevent resume
   return fail which casue IO hang.

Signed-off-by: Peter Wang <peter.wang@mediatek.com>
---
 drivers/ufs/core/ufshcd.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
diff mbox series

Patch

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 129446775796..bc30a0842277 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -2863,6 +2863,14 @@  static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 		 * being issued in that case.
 		 */
 		if (ufshcd_eh_in_progress(hba)) {
+			/* Same as UFSHCD_STATE_EH_SCHEDULED_FATAL */
+			if (hba->pm_op_in_progress) {
+				hba->force_reset = true;
+				set_host_byte(cmd, DID_BAD_TARGET);
+				scsi_done(cmd);
+				goto out;
+			}
+
 			err = SCSI_MLQUEUE_HOST_BUSY;
 			goto out;
 		}
@@ -9784,6 +9792,9 @@  static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 
 	if (!ufshcd_is_ufs_dev_active(hba)) {
 		ret = ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE);
+		/* Try prevent return error, else IO hang */
+		if (ret)
+			ret = ufshcd_link_recovery(hba);
 		if (ret)
 			goto set_old_link_state;
 		ufshcd_set_timestamp_attr(hba);