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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox