[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251025160905.3857885-400-sashal@kernel.org>
Date: Sat, 25 Oct 2025 12:00:31 -0400
From: Sasha Levin <sashal@...nel.org>
To: patches@...ts.linux.dev,
stable@...r.kernel.org
Cc: Peter Wang <peter.wang@...iatek.com>,
"Martin K. Petersen" <martin.petersen@...cle.com>,
Sasha Levin <sashal@...nel.org>,
matthias.bgg@...il.com,
angelogioacchino.delregno@...labora.com,
linux-scsi@...r.kernel.org,
linux-mediatek@...ts.infradead.org,
linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org
Subject: [PATCH AUTOSEL 6.17-6.1] scsi: ufs: host: mediatek: Enhance recovery on resume failure
From: Peter Wang <peter.wang@...iatek.com>
[ Upstream commit 15ef3f5aa822f32524cba1463422a2c9372443f0 ]
Improve the recovery process for failed resume operations. Log the
device's power status and return 0 if both resume and recovery fail to
prevent I/O hang.
Signed-off-by: Peter Wang <peter.wang@...iatek.com>
Signed-off-by: Martin K. Petersen <martin.petersen@...cle.com>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
LLM Generated explanations, may be completely bogus:
YES
Explanation
- What changed (drivers/ufs/host/ufs-mediatek.c: fail path in
`ufs_mtk_resume()`):
- Old behavior: on resume failure, jump to `fail:` and return
`ufshcd_link_recovery(hba)` (propagate error).
- New behavior: at `fail:` call `ufshcd_link_recovery(hba)` and log
runtime PM status if it fails; then unconditionally `return 0 /*
Cannot return a failure, otherwise, the I/O will hang. */`.
- Code reference: drivers/ufs/host/ufs-mediatek.c:1814 (call to
`ufshcd_link_recovery(hba)`), followed by the new `dev_err()` that
prints `hba->dev->power.request`, `runtime_status`, `runtime_error`,
and the unconditional `return 0`.
- Why this fixes a real bug affecting users (I/O hang):
- The UFS core resume path calls the vendor resume first and bails out
immediately if the vops `resume()` returns an error, skipping core
recovery steps like hibern8 exit or full reset/restore:
- Code reference: drivers/ufs/core/ufshcd.c:10011 (`ret =
ufshcd_vops_resume(hba, pm_op); if (ret) goto out;`).
- If the Mediatek variant previously returned an error from
`ufs_mtk_resume()`, the core code would not attempt
`ufshcd_uic_hibern8_exit()` or `ufshcd_reset_and_restore()`,
leaving the link/device in a bad state and causing I/O to hang.
- With this patch, the Mediatek driver tries `ufshcd_link_recovery()`
locally and returns 0, allowing the core resume sequence to proceed:
- If the link is in Hibern8, the core performs
`ufshcd_uic_hibern8_exit()` (drivers/ufs/core/ufshcd.c:10025) and
sets the link active.
- If the link is off, the core performs `ufshcd_reset_and_restore()`
(drivers/ufs/core/ufshcd.c:10034).
- Hence, even if the vendor-specific parts hit an error, the core
still executes its well-tested recovery and bring-up, which avoids
the I/O hang scenario the commit message calls out.
- Localized change, minimal risk:
- The change is confined to one function in the Mediatek UFS host
driver; no interface or architectural changes.
- `ufshcd_link_recovery()` is the standard core recovery path for UFS
(drivers/ufs/core/ufshcd.c:4467), which resets the device and host
and is safe to invoke on failures.
- Logging uses existing runtime PM fields for debugging and has no
functional side effects.
- Side effects considered:
- Masking the error return from `ufshcd_link_recovery()` at the
variant level does not hide failures overall: subsequent core steps
will still return errors if the link/device is not brought back
correctly, and the resume wrapper will report failure
(drivers/ufs/core/ufshcd.c:10011+ path).
- This approach improves robustness by ensuring core recovery always
runs, which is preferable to aborting early and risking an
unrecovered link and stuck I/O.
- Stable backport criteria:
- Fixes a user-visible bug (I/O hang after resume failures).
- Patch is small, self-contained, and limited to Mediatek UFS host
driver.
- No new features or API changes; follows existing error-handling
patterns (attempt recovery, proceed to core recovery, log details).
- Low regression risk relative to the severity of the hang it
prevents.
Conclusion: This is a targeted bug fix that prevents I/O hangs by
ensuring the core resume/recovery sequence runs even if the vendor
resume fails. It is suitable for backporting to stable.
drivers/ufs/host/ufs-mediatek.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index bb0be6bed1bca..188f90e468c41 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -1727,8 +1727,21 @@ static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
}
return 0;
+
fail:
- return ufshcd_link_recovery(hba);
+ /*
+ * Check if the platform (parent) device has resumed, and ensure that
+ * power, clock, and MTCMOS are all turned on.
+ */
+ err = ufshcd_link_recovery(hba);
+ if (err) {
+ dev_err(hba->dev, "Device PM: req=%d, status:%d, err:%d\n",
+ hba->dev->power.request,
+ hba->dev->power.runtime_status,
+ hba->dev->power.runtime_error);
+ }
+
+ return 0; /* Cannot return a failure, otherwise, the I/O will hang. */
}
static void ufs_mtk_dbg_register_dump(struct ufs_hba *hba)
--
2.51.0
Powered by blists - more mailing lists