[PATCH 2/2] scsi: ufs: core: Wake consumer queues on suspended W-LUN recovery

From: Stanley Jhu

Date: Thu Nov 05 2026 - 02:16:04 EST


Since commit eef1d74bf88f ("PM: runtime: Only set runtime_error on
suspend callback failures"), a failed W-LUN runtime resume leaves
ufs_device_wlun in RPM_SUSPENDED with power.runtime_error == 0. When
error recovery resets and restores the host, ufshcd_recover_pm_error()
misses consumer queue recovery and leaves waking I/O stuck:

1. Consumer I/O on a runtime-suspended logical unit blocks in
__bio_queue_enter() with pm_only set, queues pm_request_resume(), and
resumes supplier ufs_device_wlun, whose START STOP UNIT fails.
2. Consumer runtime resume aborts with pm_only still set while
ufshcd_err_handler() resets and restores the host and link, then
calls ufshcd_recover_pm_error().
3. ufshcd_recover_pm_error() checks only power.runtime_error and skips
consumer queue recovery, leaving waking I/O blocked in
__bio_queue_enter() until another request touches the same queue.

Set resume_sdev_queues when ufs_device_wlun is runtime-suspended in
ufshcd_recover_pm_error() so consumer pm_request_resume() resumes
ufs_device_wlun via the runtime PM device link and clears consumer
pm_only through sdev_runtime_resume().

Fixes: eef1d74bf88f ("PM: runtime: Only set runtime_error on suspend callback failures")
Cc: stable@xxxxxxxxxxxxxxx # v7.3+
Signed-off-by: Stanley Jhu <stanleyjhu@xxxxxxxxxx>
---
Prerequisite patches (for mainline and stable backports):
- Message-ID: <20261104112744.1630864-1-stanleyjhu@xxxxxxxxxx>
("block: Keep RPM_ACTIVE in blk_pre_runtime_resume() when already
active")
- Message-ID: <20261029040002.2100002-1-stanleyjhu@xxxxxxxxxx>
("scsi: ufs: core: Keep clock-gating hold on failed W-LUN runtime
resume")

drivers/ufs/core/ufshcd.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 4f0301d2a5d4..880a14a2c5a4 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -6953,7 +6953,9 @@ static void ufshcd_recover_pm_error(struct ufs_hba *hba)
resume_sdev_queues = true;
}

- if (hba->ufs_device_wlun->sdev_gendev.power.runtime_error) {
+ if (pm_runtime_status_suspended(&hba->ufs_device_wlun->sdev_gendev)) {
+ resume_sdev_queues = true;
+ } else if (hba->ufs_device_wlun->sdev_gendev.power.runtime_error) {
/*
* starget, parent of wlun, might be suspended if wlun resume failed.
* Make sure parent is resumed before set child (wlun) active.
--
2.56.0.385.gac671c819a-goog