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@vger.kernel.org # v7.3+ Signed-off-by: Stanley Jhu --- Prerequisite patches (for mainline and stable backports): - Message-ID: <20261104112744.1630864-1-stanleyjhu@google.com> ("block: Keep RPM_ACTIVE in blk_pre_runtime_resume() when already active") - Message-ID: <20261029040002.2100002-1-stanleyjhu@google.com> ("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