* [PATCH v3 0/2] scsi: ufs: core: Avoid redundant link recovery during system resume
[not found] <CGME20261026044138epcas2p19feb1c8130a1c07b67b1f27eefb1c300@epcas2p1.samsung.com>
@ 2026-10-26 4:37 ` HOYOUNG SEO
[not found] ` <CGME20261026044139epcas2p3a5b55ec93b313eeb9a38bbf0c93cf889@epcas2p3.samsung.com>
[not found] ` <CGME20261026044140epcas2p3e83872a5701a30853937a40e16511e49@epcas2p3.samsung.com>
0 siblings, 2 replies; 3+ messages in thread
From: HOYOUNG SEO @ 2026-10-26 4:37 UTC (permalink / raw)
To: linux-scsi, linux-kernel, alim.akhtar, avri.altman, jejb,
martin.petersen, bvanassche, kwangwon.min, kwmad.kim, cpgs,
h10.kim
Cc: HOYOUNG SEO
If a LINERESET is reported and the hibern8 exit fails during system
resume, both ufshcd_err_handler() and __ufshcd_wl_resume() call
ufshcd_link_recovery(), and the two recoveries are not serialized.
Patch 1 makes ufshcd_link_recovery() clear the saved errors like
ufshcd_reset_and_restore() does, so the error handler does not act on
errors that have already been recovered.
Patch 2 makes ufshcd_err_handler() wait for host_sem instead of
recovering the link early when the hba is system suspended.
Changes in v2:
- Add patch 1. As pointed out by the Sashiko review, saved_err and
saved_uic_err are still set after the resume path recovered the link,
so with v1 alone ufshcd_err_handler() would run a redundant recovery
once host_sem is released.
- Patch 2: describe the race and the system/runtime PM difference in
the commit message, and add a comment.
Changes in v3:
- Patch 2: reword the commit message only, no code change. The error
handler does not always run a full recovery after a failed system
resume; it stops according to ufshcd_err_handling_should_stop() (e.g.
in UFSHCD_STATE_ERROR). Describe this behavior and refer to the commit
that added the early link recovery (Sashiko review).
- Patch 1: no change.
HOYOUNG SEO (2):
scsi: ufs: core: Clear saved errors in ufshcd_link_recovery
scsi: ufs: core: add is_sys_suspended state before recovery
drivers/ufs/core/ufshcd.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v3 1/2] scsi: ufs: core: Clear saved errors in ufshcd_link_recovery
[not found] ` <CGME20261026044139epcas2p3a5b55ec93b313eeb9a38bbf0c93cf889@epcas2p3.samsung.com>
@ 2026-10-26 4:37 ` HOYOUNG SEO
0 siblings, 0 replies; 3+ messages in thread
From: HOYOUNG SEO @ 2026-10-26 4:37 UTC (permalink / raw)
To: linux-scsi, linux-kernel, alim.akhtar, avri.altman, jejb,
martin.petersen, bvanassche, kwangwon.min, kwmad.kim, cpgs,
h10.kim
Cc: HOYOUNG SEO
ufshcd_link_recovery() resets both the device and the host and then
re-establishes the link. Unlike ufshcd_reset_and_restore(), however, it
does not clear hba->saved_err, hba->saved_uic_err and hba->force_reset,
so the errors latched before the recovery remain pending after the link
has already been recovered.
When ufshcd_err_handler() runs afterwards,
ufshcd_err_handling_should_stop() sees these stale errors. The error
handler then quiesces all queues and, depending on the latched errors
(e.g. a fatal error or UFSHCD_UIC_DL_PA_INIT_ERROR), performs another
full ufshcd_reset_and_restore() on a link that is already operational.
Cache and clear the saved errors before the reset, as
ufshcd_reset_and_restore() does, so that only errors raised during or
after the recovery are left to the error handler. Put them back if the
recovery fails.
Signed-off-by: HOYOUNG SEO <hy50.seo@samsung.com>
---
drivers/ufs/core/ufshcd.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index bcc2512bf34b..74dfbb98129e 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -4690,10 +4690,20 @@ EXPORT_SYMBOL_GPL(ufshcd_uic_change_pwr_mode);
int ufshcd_link_recovery(struct ufs_hba *hba)
{
+ u32 saved_err, saved_uic_err;
int ret;
unsigned long flags;
spin_lock_irqsave(&hba->host->host_lock, flags);
+ /*
+ * The errors saved so far are handled by this full reset, so cache and
+ * clear them first, in case new errors are generated during recovery.
+ */
+ saved_err = hba->saved_err;
+ saved_uic_err = hba->saved_uic_err;
+ hba->saved_err = 0;
+ hba->saved_uic_err = 0;
+ hba->force_reset = false;
hba->ufshcd_state = UFSHCD_STATE_RESET;
ufshcd_set_eh_in_progress(hba);
spin_unlock_irqrestore(&hba->host->host_lock, flags);
@@ -4704,8 +4714,11 @@ int ufshcd_link_recovery(struct ufs_hba *hba)
ret = ufshcd_host_reset_and_restore(hba);
spin_lock_irqsave(&hba->host->host_lock, flags);
- if (ret)
+ if (ret) {
hba->ufshcd_state = UFSHCD_STATE_ERROR;
+ hba->saved_err |= saved_err;
+ hba->saved_uic_err |= saved_uic_err;
+ }
ufshcd_clear_eh_in_progress(hba);
spin_unlock_irqrestore(&hba->host->host_lock, flags);
--
2.34.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v3 2/2] scsi: ufs: core: add is_sys_suspended state before recovery
[not found] ` <CGME20261026044140epcas2p3e83872a5701a30853937a40e16511e49@epcas2p3.samsung.com>
@ 2026-10-26 4:37 ` HOYOUNG SEO
0 siblings, 0 replies; 3+ messages in thread
From: HOYOUNG SEO @ 2026-10-26 4:37 UTC (permalink / raw)
To: linux-scsi, linux-kernel, alim.akhtar, avri.altman, jejb,
martin.petersen, bvanassche, kwangwon.min, kwmad.kim, cpgs,
h10.kim
Cc: HOYOUNG SEO
If a LINERESET is reported and the hibern8 exit fails in
__ufshcd_wl_resume() during system resume, the link is recovered twice:
- the UIC error interrupt schedules eh_work, and ufshcd_err_handler()
calls ufshcd_link_recovery() because hba->pm_op_in_progress is set;
- __ufshcd_wl_resume() calls ufshcd_link_recovery() itself after the
hibern8 exit failure.
Since the early recovery path in ufshcd_err_handler() does not take
hba->host_sem, the two recoveries are not serialized and may reset the
host and the device concurrently.
During system resume, hba->host_sem is held from ufshcd_wl_suspend()
until ufshcd_wl_resume() returns, so the error handler can simply wait
for it. Skip the early link recovery when hba->is_sys_suspended is set.
Once host_sem is released, ufshcd_err_handler() decides as usual with
ufshcd_err_handling_should_stop(). With the previous patch, the errors
already recovered by the resume path are cleared, so it stops unless new
errors occurred. If the resume failed before any recovery was done, the
pending errors are still set and it runs the regular error handling. If
the recovery in the resume path failed, the HBA is in
UFSHCD_STATE_ERROR and the error handler does not retry.
The early link recovery added by commit f966e02ae521 ("scsi: ufs: core:
Fix runtime suspend error deadlock") is kept for runtime PM, where
host_sem is not held and the error handler cannot wait for the PM
operation to finish.
Signed-off-by: HOYOUNG SEO <hy50.seo@samsung.com>
---
drivers/ufs/core/ufshcd.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 74dfbb98129e..d085d394858f 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -7053,9 +7053,14 @@ static void ufshcd_err_handler(struct work_struct *work)
* runtime resume. This avoids potential deadlocks that could
* happen if we tried to resume the device while a PM operation
* is already in progress.
+ *
+ * During system resume, host_sem is held from
+ * ufshcd_wl_suspend() until ufshcd_wl_resume() returns, so wait
+ * for it below instead of recovering the link concurrently with
+ * the resume path.
*/
ufshcd_rpm_get_noresume(hba);
- if (hba->pm_op_in_progress) {
+ if (hba->pm_op_in_progress && !hba->is_sys_suspended) {
ufshcd_link_recovery(hba);
ufshcd_rpm_put(hba);
return;
--
2.34.1
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-26 4:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <CGME20261026044138epcas2p19feb1c8130a1c07b67b1f27eefb1c300@epcas2p1.samsung.com>
2026-10-26 4:37 ` [PATCH v3 0/2] scsi: ufs: core: Avoid redundant link recovery during system resume HOYOUNG SEO
[not found] ` <CGME20261026044139epcas2p3a5b55ec93b313eeb9a38bbf0c93cf889@epcas2p3.samsung.com>
2026-10-26 4:37 ` [PATCH v3 1/2] scsi: ufs: core: Clear saved errors in ufshcd_link_recovery HOYOUNG SEO
[not found] ` <CGME20261026044140epcas2p3e83872a5701a30853937a40e16511e49@epcas2p3.samsung.com>
2026-10-26 4:37 ` [PATCH v3 2/2] scsi: ufs: core: add is_sys_suspended state before recovery HOYOUNG SEO
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®