From: sashiko-bot@kernel.org
To: "HOYOUNG SEO" <hy50.seo@samsung.com>, linux-scsi@vger.kernel.org
Subject: Re: [PATCH v9 2/3] scsi: ufs: core: Hold host_sem in ufshcd_wl_poweroff()
Date: Tue, 10 Nov 2026 02:39:47 +0000 [thread overview]
Message-ID: <sashiko-outbox-206058@kernel.org> (raw)
In-Reply-To: <973576304.21794277202839.JavaMail.epsvc@epcpadp1new>
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [High] scsi: ufs: core: ufshcd_wl_poweroff() fails on
runtime-suspended WLUN
- [Medium] scsi: ufs: core: missing is_sys_suspended set in
ufshcd_wl_poweroff()
- [Medium] scsi: ufs: core: unnormalized return value in
ufshcd_wl_poweroff()
--
commit adb43cfc03f9f1ca024eaa8ee5c87641ce38cdf8
Author: HOYOUNG SEO <hy50.seo@samsung.com>
scsi: ufs: core: Hold host_sem in ufshcd_wl_poweroff()
This commit acquires hba->host_sem in ufshcd_wl_poweroff() before calling
__ufshcd_wl_suspend() and propagates any error returned by
__ufshcd_wl_suspend().
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index d95b929b282da..688760a98d4b4 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -11586,9 +11586,15 @@ static int ufshcd_wl_poweroff(struct device *dev)
> {
> struct scsi_device *sdev = to_scsi_device(dev);
> struct ufs_hba *hba = shost_priv(sdev->host);
> + int ret;
>
> - __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM);
> - return 0;
> + /* Released by ufshcd_wl_resume() if hibernation is aborted. */
> + down(&hba->host_sem);
> + ret = __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM);
> + if (ret)
> + up(&hba->host_sem);
> +
> + return ret;
> }
> #endif
[Severity: High]
Can ufshcd_wl_poweroff() fail with -EBUSY when hba->ufs_device_wlun is
runtime-suspended?
During hibernation prepare, __ufshcd_suspend_prepare() leaves
ufs_device_wlun runtime-suspended whenever ufshcd_rpm_ok_for_spm(hba) is
true (for example, when hba->rpm_lvl and hba->spm_lvl are both
UFS_PM_LVL_3). Unlike ufshcd_wl_suspend() (which checks
pm_runtime_suspended(dev)) and ufshcd_wl_shutdown() (which calls
ufshcd_rpm_get_sync(hba) first), ufshcd_wl_poweroff() calls
__ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM) directly:
drivers/ufs/core/ufshcd.c:__ufshcd_wl_suspend() {
...
/* UFS device & link must be active before we enter in this function */
if (!ufshcd_is_ufs_dev_active(hba) || !ufshcd_is_link_active(hba)) {
/* Wait err handler finish or trigger err recovery */
if (!ufshcd_eh_in_progress(hba))
ufshcd_force_error_recovery(hba);
ret = -EBUSY;
goto enable_scaling;
}
...
}
When the WLUN is runtime-suspended in UFS_SLEEP_PWR_MODE /
UIC_LINK_HIBERN8_STATE, __ufshcd_wl_suspend() triggers error recovery,
clears hba->clk_gating.is_suspended while runtime-suspended, and returns
-EBUSY. Propagating ret from ufshcd_wl_poweroff() then causes
dpm_suspend_start(PMSG_HIBERNATE) to fail and abort hibernation.
In addition, if the WLUN is runtime-suspended at UFS_PM_LVL_5
(UFS_POWERDOWN_PWR_MODE and UIC_LINK_OFF_STATE), __ufshcd_wl_suspend()
takes a second ufshcd_hold(hba) reference and returns 0 via the
enable_scaling path without releasing it. If hibernation is later
aborted, ufshcd_wl_resume() skips __ufshcd_wl_resume() because
pm_runtime_suspended(dev) is true, leaking that ufshcd_hold(hba)
reference.
[Severity: Medium]
Should ufshcd_wl_poweroff() also set hba->is_sys_suspended = true when
__ufshcd_wl_suspend() succeeds, matching ufshcd_wl_suspend()?
If hibernation is aborted after ufshcd_wl_poweroff() succeeds and the
subsequent .restore callback (ufshcd_wl_resume()) fails in
__ufshcd_wl_resume(), ufshcd_wl_resume() releases hba->host_sem so
ufshcd_err_handler() can recover the link:
drivers/ufs/core/ufshcd.c:ufshcd_err_handling_prepare() {
...
if (pm_runtime_status_suspended(&hba->ufs_device_wlun->sdev_gendev) ||
hba->is_sys_suspended) {
enum ufs_pm_op pm_op;
...
pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM;
ufshcd_vops_resume(hba, pm_op);
}
...
}
Because hba->is_sys_suspended was never set to true,
ufshcd_err_handling_prepare() sees both pm_runtime_status_suspended() and
hba->is_sys_suspended as false, skipping regulator, IRQ, and clock
restoration as well as ufshcd_vops_resume(hba, UFS_SYSTEM_PM) during error
recovery.
[Severity: Medium]
Can ufshcd_wl_poweroff() return a positive UIC status code and skip error
recovery when a power mode or link state transition fails?
In __ufshcd_wl_suspend(), the error handling blocks after
ufshcd_set_dev_pwr_mode() and ufshcd_link_state_transition() are guarded
by pm_op != UFS_SHUTDOWN_PM:
drivers/ufs/core/ufshcd.c:__ufshcd_wl_suspend() {
...
ret = ufshcd_link_state_transition(hba, req_link_state, check_for_bkops);
if (ret && pm_op != UFS_SHUTDOWN_PM) {
ufshcd_force_error_recovery(hba);
ret = -EBUSY;
}
if (ret)
goto set_dev_active;
...
}
When ufshcd_uic_pwr_ctrl() fails with a non-PWR_LOCAL status in
ufshcd_get_upmcrs(hba), it skips scheduling eh_work because
hba->pm_op_in_progress is true and returns that positive UPMCRS status
code. Because ufshcd_wl_poweroff() passes UFS_SHUTDOWN_PM,
__ufshcd_wl_suspend() neither calls ufshcd_force_error_recovery(hba) nor
normalizes ret to -EBUSY, so power_down() in kernel/power/hibernate.c
(which only rolls back on -EBUSY or -EAGAIN) does not roll back
hibernation cleanly and error recovery is not scheduled if hibernation
aborts.
--
Sashiko AI review · https://sashiko.dev/#/patchset/1582071873.61794277203231.JavaMail.epsvc@epcpadp1new?part=2
next prev parent reply other threads:[~2026-11-10 2:39 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20261110020746epcas2p2ed2c3b150d2ecbf810658264841e790e@epcas2p2.samsung.com>
[not found] ` <cover.1794275305.git.hy50.seo@samsung.com>
2026-11-10 2:03 ` [PATCH v9 1/3] scsi: ufs: core: Clear saved errors in ufshcd_link_recovery() HOYOUNG SEO
2026-11-10 2:03 ` [PATCH v9 2/3] scsi: ufs: core: Hold host_sem in ufshcd_wl_poweroff() HOYOUNG SEO
2026-11-10 2:39 ` sashiko-bot [this message]
2026-11-10 5:50 ` Peter Wang
2026-11-10 17:53 ` Bart Van Assche
2026-11-10 2:03 ` [PATCH v9 3/3] scsi: ufs: core: Limit early link recovery in the error handler to runtime PM HOYOUNG SEO
2026-11-10 5:51 ` Peter Wang
2026-11-10 17:54 ` Bart Van Assche
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-206058@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=hy50.seo@samsung.com \
--cc=linux-scsi@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.