mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/5] scsi: ufs: Fix device management timeouts and runtime PM errors
@ 2026-10-25  1:34 Stanley Jhu
  2026-10-25  1:34 ` [PATCH 1/5] scsi: ufs: core: Restore jiffies conversion of device management timeouts Stanley Jhu
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Stanley Jhu @ 2026-10-25  1:34 UTC (permalink / raw)
  To: Martin K . Petersen, James E . J . Bottomley
  Cc: Alim Akhtar, Bart Van Assche, Bean Huo, Can Guo, Peter Wang,
	linux-scsi, linux-kernel, Stanley Jhu

This series fixes two problems in UFS core entry points that issue
device management commands or touch host registers.

Patch 1/5 restores the millisecond to jiffies conversion of device
management command timeouts. Since the timeout moved to rq->timeout,
a 1500 ms query timeout waits 6 s with CONFIG_HZ=250.

Patches 2/5 to 5/5 handle runtime PM resume errors. Several UFS core,
sysfs, BSG, hwmon, and debugfs entry points call ufshcd_rpm_get_sync()
before accessing host registers or issuing device management and UIC
commands, but ignore its return value.

ufshcd_rpm_get_sync() wraps pm_runtime_get_sync() on the UFS device
W-LUN and returns a negative errno in three situations:
- Runtime resume of the W-LUN or host controller fails, leaving the
  device or controller in RPM_SUSPENDED with runtime_error clear.
- A prior runtime suspend failure latched power.runtime_error, so
  pm_runtime_get_sync() fails immediately with -EINVAL.
- Runtime PM is disabled on a non-active W-LUN, such as after
  device_suspend_late(), so pm_runtime_get_sync() fails with -EACCES.

Continuing after those failures can access host registers or issue
commands while the device or controller is not known to be active,
while checking pm_runtime_get_sync() directly would leave
power.usage_count elevated unless balanced with
pm_runtime_put_noidle().

Add ufshcd_rpm_resume_and_get() around pm_runtime_resume_and_get() and
convert the 20 external and helper call sites to abort and propagate the
error when resuming the W-LUN fails. The three lifecycle call sites in
ufshcd_rpm_dev_flush_recheck_work(), ufshcd_wl_shutdown(), and
ufshcd_remove(), plus ufshcd_err_handling_prepare(), are intentionally
left unchanged.

Tested on QEMU ARM64 UFS (SDB and MCQ) with injected runtime resume,
runtime suspend, and late-suspend failures, and with a timed out query
request.

Stanley Jhu (5):
  scsi: ufs: core: Restore jiffies conversion of device management
    timeouts
  scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper
  scsi: ufs: sysfs: Propagate runtime PM resume errors
  scsi: ufs: bsg: Abort ufs_bsg_request() when runtime resume fails
  scsi: ufs: hwmon, debugfs: Propagate runtime PM resume errors

 drivers/ufs/core/ufs-debugfs.c |  8 +++-
 drivers/ufs/core/ufs-hwmon.c   | 12 +++++-
 drivers/ufs/core/ufs-sysfs.c   | 67 +++++++++++++++++++++++++++-------
 drivers/ufs/core/ufs_bsg.c     |  4 +-
 drivers/ufs/core/ufshcd-priv.h |  5 +++
 drivers/ufs/core/ufshcd.c      |  9 +++--
 6 files changed, 84 insertions(+), 21 deletions(-)

-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] scsi: ufs: core: Restore jiffies conversion of device management timeouts
  2026-10-25  1:34 [PATCH 0/5] scsi: ufs: Fix device management timeouts and runtime PM errors Stanley Jhu
@ 2026-10-25  1:34 ` Stanley Jhu
  2026-10-25  1:34 ` [PATCH 2/5] scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper Stanley Jhu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Stanley Jhu @ 2026-10-25  1:34 UTC (permalink / raw)
  To: Martin K . Petersen, James E . J . Bottomley
  Cc: Alim Akhtar, Bart Van Assche, Bean Huo, Can Guo, Peter Wang,
	linux-scsi, linux-kernel, Stanley Jhu, stable

Before commit 08b12cda6c44 ("scsi: ufs: core: Switch to
scsi_get_internal_cmd()"), ufshcd_wait_for_dev_cmd() converted the
millisecond timeout with msecs_to_jiffies() before waiting for the
command. That commit moved the timeout to the block layer and assigns
the millisecond value to rq->timeout as is, but rq->timeout is in
jiffies. A 1500 ms query timeout (QUERY_REQ_TIMEOUT_DEFAULT) becomes
6 s with CONFIG_HZ=250 and 15 s with CONFIG_HZ=100, and NOP_OUT_TIMEOUT
and ADVANCED_RPMB_REQ_TIMEOUT grow the same way.

Restore the conversion with msecs_to_jiffies().

Fixes: 08b12cda6c44 ("scsi: ufs: core: Switch to scsi_get_internal_cmd()")
Cc: stable@vger.kernel.org # v6.19+
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
---
 drivers/ufs/core/ufshcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index ee643830a57a..5193be703752 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3390,7 +3390,7 @@ static int ufshcd_issue_dev_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd,
 	struct request *rq = scsi_cmd_to_rq(cmd);
 	blk_status_t sts;
 
-	rq->timeout = timeout;
+	rq->timeout = msecs_to_jiffies(timeout);
 	sts = blk_execute_rq(rq, true);
 	if (sts != BLK_STS_OK)
 		return blk_status_to_errno(sts);
-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/5] scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper
  2026-10-25  1:34 [PATCH 0/5] scsi: ufs: Fix device management timeouts and runtime PM errors Stanley Jhu
  2026-10-25  1:34 ` [PATCH 1/5] scsi: ufs: core: Restore jiffies conversion of device management timeouts Stanley Jhu
@ 2026-10-25  1:34 ` Stanley Jhu
  2026-10-25  1:34 ` [PATCH 3/5] scsi: ufs: sysfs: Propagate runtime PM resume errors Stanley Jhu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Stanley Jhu @ 2026-10-25  1:34 UTC (permalink / raw)
  To: Martin K . Petersen, James E . J . Bottomley
  Cc: Alim Akhtar, Bart Van Assche, Bean Huo, Can Guo, Peter Wang,
	linux-scsi, linux-kernel, Stanley Jhu, stable

ufshcd_clkscale_enable_store() and ufshcd_auto_hibern8_update() call
ufshcd_rpm_get_sync() without checking its return value:

1. Runtime resume of the UFS device W-LUN fails and leaves the W-LUN in
   RPM_SUSPENDED, or a prior runtime suspend error latches
   power.runtime_error, or runtime PM is disabled while suspended so
   !pm_runtime_suspended() still evaluates to true.
2. ufshcd_rpm_get_sync() returns a negative errno and leaves
   power.usage_count incremented.
3. Both functions proceed as if the host were active, scaling clocks or
   writing REG_AUTO_HIBERNATE_IDLE_TIMER while the controller or link
   is still suspended.

Add ufshcd_rpm_resume_and_get() wrapping pm_runtime_resume_and_get() so
failed resumes drop the usage reference automatically, and return early
in ufshcd_clkscale_enable_store() and ufshcd_auto_hibern8_update() when
it fails.

Fixes: b294ff3e3449 ("scsi: ufs: core: Enable power management for wlun")
Cc: stable@vger.kernel.org
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
---
 drivers/ufs/core/ufshcd-priv.h | 5 +++++
 drivers/ufs/core/ufshcd.c      | 7 +++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
index e55c2a02c1f5..99f654b79035 100644
--- a/drivers/ufs/core/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -388,6 +388,11 @@ static inline int ufshcd_rpm_get_sync(struct ufs_hba *hba)
 	return pm_runtime_get_sync(&hba->ufs_device_wlun->sdev_gendev);
 }
 
+static inline int ufshcd_rpm_resume_and_get(struct ufs_hba *hba)
+{
+	return pm_runtime_resume_and_get(&hba->ufs_device_wlun->sdev_gendev);
+}
+
 static inline int ufshcd_rpm_get_if_active(struct ufs_hba *hba)
 {
 	return pm_runtime_get_if_active(&hba->ufs_device_wlun->sdev_gendev);
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 5193be703752..2d73dc7d68a9 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -1864,7 +1864,9 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev,
 	if (value == hba->clk_scaling.is_enabled)
 		goto out;
 
-	ufshcd_rpm_get_sync(hba);
+	err = ufshcd_rpm_resume_and_get(hba);
+	if (err)
+		goto out;
 	ufshcd_hold(hba);
 
 	hba->clk_scaling.is_enabled = value;
@@ -4792,7 +4794,8 @@ void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit)
 
 	WRITE_ONCE(hba->ahit, ahit);
 	if (!pm_runtime_suspended(&hba->ufs_device_wlun->sdev_gendev)) {
-		ufshcd_rpm_get_sync(hba);
+		if (ufshcd_rpm_resume_and_get(hba))
+			return;
 		ufshcd_hold(hba);
 		/*
 		 * Serialize with the host driver's AHIT control. Skip the
-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/5] scsi: ufs: sysfs: Propagate runtime PM resume errors
  2026-10-25  1:34 [PATCH 0/5] scsi: ufs: Fix device management timeouts and runtime PM errors Stanley Jhu
  2026-10-25  1:34 ` [PATCH 1/5] scsi: ufs: core: Restore jiffies conversion of device management timeouts Stanley Jhu
  2026-10-25  1:34 ` [PATCH 2/5] scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper Stanley Jhu
@ 2026-10-25  1:34 ` Stanley Jhu
  2026-10-25  1:34 ` [PATCH 4/5] scsi: ufs: bsg: Abort ufs_bsg_request() when runtime resume fails Stanley Jhu
  2026-10-25  1:34 ` [PATCH 5/5] scsi: ufs: hwmon, debugfs: Propagate runtime PM resume errors Stanley Jhu
  4 siblings, 0 replies; 6+ messages in thread
From: Stanley Jhu @ 2026-10-25  1:34 UTC (permalink / raw)
  To: Martin K . Petersen, James E . J . Bottomley
  Cc: Alim Akhtar, Bart Van Assche, Bean Huo, Can Guo, Peter Wang,
	linux-scsi, linux-kernel, Stanley Jhu, stable

All 14 ufshcd_rpm_get_sync() callers in ufs-sysfs.c ignore its return
value:

1. A user-space sysfs read or write runs when W-LUN runtime resume
   fails, when power.runtime_error is set from a failed runtime
   suspend, or when W-LUN runtime PM is disabled while not active.
2. ufshcd_rpm_get_sync() returns a negative errno without waking the
   device or host controller.
3. ufshcd_read_hci_reg() reads an HCI MMIO register on an unresumed
   controller, and the remaining handlers issue query UPIUs over a
   suspended or broken link.

Switch all 14 sysfs callers to ufshcd_rpm_resume_and_get() and return
the error after releasing any held buffer and hba->host_sem.

Fixes: aef80fd1da32 ("scsi: ufs: sysfs: Resume the proper SCSI device")
Fixes: b9d104465a6c ("scsi: ufs: Prepare to add HCI capabilities sysfs")
Fixes: 600edc6620a4 ("scsi: ufs: sysfs: Make max_number_of_rtt read-write")
Fixes: 6c4148ce7cc1 ("scsi: ufs: wb: Add explicit flush sysfs attribute")
Fixes: 500d4b742e0c ("scsi: ufs: core: Add WB buffer resize support")
Fixes: ae7795a8c258 ("scsi: ufs: core: Add HID support")
Fixes: 1fd2e77b8897 ("scsi: ufs: core: Add device level exception support")
Cc: stable@vger.kernel.org # needs "scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper"
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
---
 drivers/ufs/core/ufs-sysfs.c | 67 ++++++++++++++++++++++++++++--------
 1 file changed, 53 insertions(+), 14 deletions(-)

diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
index cf49ad0258e1..19b62cf52410 100644
--- a/drivers/ufs/core/ufs-sysfs.c
+++ b/drivers/ufs/core/ufs-sysfs.c
@@ -250,13 +250,19 @@ EXPORT_SYMBOL_GPL(ufshcd_us_to_ahit);
 
 static int ufshcd_read_hci_reg(struct ufs_hba *hba, u32 *val, unsigned int reg)
 {
+	int ret;
+
 	down(&hba->host_sem);
 	if (!ufshcd_is_user_access_allowed(hba)) {
 		up(&hba->host_sem);
 		return -EBUSY;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret) {
+		up(&hba->host_sem);
+		return ret;
+	}
 	ufshcd_hold(hba);
 	*val = ufshcd_readl(hba, reg);
 	ufshcd_release(hba);
@@ -350,7 +356,9 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr,
 		goto out;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	res = ufshcd_rpm_resume_and_get(hba);
+	if (res)
+		goto out;
 	res = ufshcd_wb_toggle(hba, wb_enable);
 	ufshcd_rpm_put_sync(hba);
 out:
@@ -421,7 +429,9 @@ static ssize_t enable_wb_buf_flush_store(struct device *dev,
 		goto out;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	res = ufshcd_rpm_resume_and_get(hba);
+	if (res)
+		goto out;
 	res = ufshcd_wb_toggle_buf_flush(hba, enable_wb_buf_flush);
 	ufshcd_rpm_put_sync(hba);
 
@@ -490,7 +500,9 @@ static ssize_t wb_resize_enable_store(struct device *dev,
 		goto out;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	res = ufshcd_rpm_resume_and_get(hba);
+	if (res)
+		goto out;
 	res = ufshcd_wb_set_resize_en(hba, mode);
 	ufshcd_rpm_put_sync(hba);
 
@@ -598,7 +610,9 @@ static ssize_t device_lvl_exception_id_show(struct device *dev,
 	if (hba->dev_info.wspecversion < 0x410)
 		return -EOPNOTSUPP;
 
-	ufshcd_rpm_get_sync(hba);
+	err = ufshcd_rpm_resume_and_get(hba);
+	if (err)
+		return err;
 	err = ufshcd_query_attr_qword(hba, UPIU_QUERY_OPCODE_READ_ATTR,
 				      QUERY_ATTR_IDN_DEV_LVL_EXCEPTION_ID,
 				      0, 0, &exception_id);
@@ -1101,7 +1115,9 @@ static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
 		goto out;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret)
+		goto out;
 	ret = ufshcd_read_desc_param(hba, desc_id, desc_index,
 				param_offset, desc_buf, param_size);
 	ufshcd_rpm_put_sync(hba);
@@ -1482,7 +1498,12 @@ static ssize_t _name##_show(struct device *dev,				\
 		up(&hba->host_sem);					\
 		return -ENOMEM;						\
 	}								\
-	ufshcd_rpm_get_sync(hba);					\
+	ret = ufshcd_rpm_resume_and_get(hba);				\
+	if (ret) {							\
+		kfree(desc_buf);					\
+		up(&hba->host_sem);					\
+		return ret;						\
+	}								\
 	ret = ufshcd_query_descriptor_retry(hba,			\
 		UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_DEVICE,	\
 		0, 0, desc_buf, &desc_len);				\
@@ -1548,7 +1569,9 @@ static ssize_t _name##_show(struct device *dev,				\
 	}								\
 	if (ufshcd_is_wb_flags(QUERY_FLAG_IDN##_uname))			\
 		index = ufshcd_wb_get_query_index(hba);			\
-	ufshcd_rpm_get_sync(hba);					\
+	ret = ufshcd_rpm_resume_and_get(hba);				\
+	if (ret)							\
+		goto out;						\
 	ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,	\
 		QUERY_FLAG_IDN##_uname, index, &flag);			\
 	ufshcd_rpm_put_sync(hba);					\
@@ -1608,7 +1631,9 @@ static ssize_t max_number_of_rtt_show(struct device *dev,
 		return -EBUSY;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret)
+		goto out;
 	ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
 		QUERY_ATTR_IDN_MAX_NUM_OF_RTT, 0, 0, &rtt);
 	ufshcd_rpm_put_sync(hba);
@@ -1648,7 +1673,9 @@ static ssize_t max_number_of_rtt_store(struct device *dev,
 		goto out;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret)
+		goto out;
 
 	memflags = memalloc_noio_save();
 	shost_for_each_device(sdev, hba->host)
@@ -1700,7 +1727,11 @@ static int wb_read_resize_attrs(struct ufs_hba *hba,
 	}
 
 	index = ufshcd_wb_get_query_index(hba);
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret) {
+		up(&hba->host_sem);
+		return ret;
+	}
 	ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
 			idn, index, 0, attr_val);
 	ufshcd_rpm_put_sync(hba);
@@ -1760,7 +1791,9 @@ static ssize_t _name##_show(struct device *dev,				\
 	}								\
 	if (ufshcd_is_wb_attrs(QUERY_ATTR_IDN##_uname))			\
 		index = ufshcd_wb_get_query_index(hba);			\
-	ufshcd_rpm_get_sync(hba);					\
+	ret = ufshcd_rpm_resume_and_get(hba);				\
+	if (ret)							\
+		goto out;						\
 	if (ufshcd_is_qword_attr(QUERY_ATTR_IDN##_uname))		\
 		ret = ufshcd_query_attr_qword(hba,			\
 			UPIU_QUERY_OPCODE_READ_ATTR,			\
@@ -1848,7 +1881,11 @@ static int hid_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
 		return -EBUSY;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret) {
+		up(&hba->host_sem);
+		return ret;
+	}
 	ret = ufshcd_query_attr(hba, opcode, idn, 0, 0, attr_val);
 	ufshcd_rpm_put_sync(hba);
 
@@ -2121,7 +2158,9 @@ static ssize_t dyn_cap_needed_attribute_show(struct device *dev,
 		goto out;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret)
+		goto out;
 	ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
 		QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value);
 	ufshcd_rpm_put_sync(hba);
-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/5] scsi: ufs: bsg: Abort ufs_bsg_request() when runtime resume fails
  2026-10-25  1:34 [PATCH 0/5] scsi: ufs: Fix device management timeouts and runtime PM errors Stanley Jhu
                   ` (2 preceding siblings ...)
  2026-10-25  1:34 ` [PATCH 3/5] scsi: ufs: sysfs: Propagate runtime PM resume errors Stanley Jhu
@ 2026-10-25  1:34 ` Stanley Jhu
  2026-10-25  1:34 ` [PATCH 5/5] scsi: ufs: hwmon, debugfs: Propagate runtime PM resume errors Stanley Jhu
  4 siblings, 0 replies; 6+ messages in thread
From: Stanley Jhu @ 2026-10-25  1:34 UTC (permalink / raw)
  To: Martin K . Petersen, James E . J . Bottomley
  Cc: Alim Akhtar, Bart Van Assche, Bean Huo, Can Guo, Peter Wang,
	linux-scsi, linux-kernel, Stanley Jhu, stable

In ufs_bsg_request(), the return value of ufshcd_rpm_get_sync() is
ignored:

1. A user-space BSG request arrives when W-LUN runtime resume fails,
   when power.runtime_error is latched, or when W-LUN runtime PM is
   disabled while not active.
2. ufshcd_rpm_get_sync() returns a negative errno without resuming the
   device.
3. ufs_bsg_request() still dispatches raw query, NOP OUT, task
   management, UIC, or advanced RPMB commands to the unresumed host.

Use ufshcd_rpm_resume_and_get() and jump to out_complete on error so the
BSG job is completed via bsg_job_done() with the failure code without
dropping an unacquired runtime PM reference.

Fixes: b294ff3e3449 ("scsi: ufs: core: Enable power management for wlun")
Cc: stable@vger.kernel.org # needs "scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper"
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
---
 drivers/ufs/core/ufs_bsg.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c
index baf6ae917d36..8df1a2c6abf6 100644
--- a/drivers/ufs/core/ufs_bsg.c
+++ b/drivers/ufs/core/ufs_bsg.c
@@ -150,7 +150,9 @@ static int ufs_bsg_request(struct bsg_job *job)
 		goto out_complete;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	ret = ufshcd_rpm_resume_and_get(hba);
+	if (ret)
+		goto out_complete;
 
 	msgcode = bsg_request->msgcode;
 	switch (msgcode) {
-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 5/5] scsi: ufs: hwmon, debugfs: Propagate runtime PM resume errors
  2026-10-25  1:34 [PATCH 0/5] scsi: ufs: Fix device management timeouts and runtime PM errors Stanley Jhu
                   ` (3 preceding siblings ...)
  2026-10-25  1:34 ` [PATCH 4/5] scsi: ufs: bsg: Abort ufs_bsg_request() when runtime resume fails Stanley Jhu
@ 2026-10-25  1:34 ` Stanley Jhu
  4 siblings, 0 replies; 6+ messages in thread
From: Stanley Jhu @ 2026-10-25  1:34 UTC (permalink / raw)
  To: Martin K . Petersen, James E . J . Bottomley
  Cc: Alim Akhtar, Bart Van Assche, Bean Huo, Can Guo, Peter Wang,
	linux-scsi, linux-kernel, Stanley Jhu, stable

ufs_hwmon_read(), ufs_hwmon_write(), and ufs_debugfs_get_user_access()
ignore the return value of ufshcd_rpm_get_sync():

1. A hwmon sensor access, a debugfs exception-event write, or a debugfs
   TX equalization retrain request runs when W-LUN runtime resume
   fails, when power.runtime_error is set, or when W-LUN runtime PM is
   disabled while suspended.
2. ufshcd_rpm_get_sync() fails with a negative errno while leaving the
   device unresumed.
3. The caller still issues temperature or exception-event query UPIUs,
   or retrains TX equalization, on the suspended target.

Convert all three call sites to ufshcd_rpm_resume_and_get() and release
hba->host_sem before returning the error, ahead of
__acquire(ufs_debugfs) in ufs_debugfs_get_user_access(). This covers
ee_usr_mask_set(), ufs_debugfs_restart_ee(), and ufs_tx_eq_ctrl_write(),
which all use ufs_debugfs_get_user_access().

Fixes: b294ff3e3449 ("scsi: ufs: core: Enable power management for wlun")
Fixes: e88e2d32200a ("scsi: ufs: core: Probe for temperature notification support")
Fixes: adbabdcf0db0 ("scsi: ufs: core: Add support to retrain TX Equalization via debugfs")
Cc: stable@vger.kernel.org # needs "scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper"
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
---
 drivers/ufs/core/ufs-debugfs.c |  8 +++++++-
 drivers/ufs/core/ufs-hwmon.c   | 12 ++++++++++--
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/ufs/core/ufs-debugfs.c b/drivers/ufs/core/ufs-debugfs.c
index 9f83628f3e2c..44a1a9692324 100644
--- a/drivers/ufs/core/ufs-debugfs.c
+++ b/drivers/ufs/core/ufs-debugfs.c
@@ -70,12 +70,18 @@ token_context_lock(ufs_debugfs);
 static int ufs_debugfs_get_user_access(struct ufs_hba *hba)
 	__cond_acquires(0, ufs_debugfs)
 {
+	int err;
+
 	down(&hba->host_sem);
 	if (!ufshcd_is_user_access_allowed(hba)) {
 		up(&hba->host_sem);
 		return -EBUSY;
 	}
-	ufshcd_rpm_get_sync(hba);
+	err = ufshcd_rpm_resume_and_get(hba);
+	if (err) {
+		up(&hba->host_sem);
+		return err;
+	}
 	__acquire(ufs_debugfs);
 	return 0;
 }
diff --git a/drivers/ufs/core/ufs-hwmon.c b/drivers/ufs/core/ufs-hwmon.c
index aa0b60a0ee8a..2b9673d92573 100644
--- a/drivers/ufs/core/ufs-hwmon.c
+++ b/drivers/ufs/core/ufs-hwmon.c
@@ -61,7 +61,11 @@ static int ufs_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32
 		return -EBUSY;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	err = ufshcd_rpm_resume_and_get(hba);
+	if (err) {
+		up(&hba->host_sem);
+		return err;
+	}
 
 	switch (attr) {
 	case hwmon_temp_enable:
@@ -113,7 +117,11 @@ static int ufs_hwmon_write(struct device *dev, enum hwmon_sensor_types type, u32
 		return -EBUSY;
 	}
 
-	ufshcd_rpm_get_sync(hba);
+	err = ufshcd_rpm_resume_and_get(hba);
+	if (err) {
+		up(&hba->host_sem);
+		return err;
+	}
 
 	if (val == 1)
 		err = ufshcd_update_ee_usr_mask(hba, MASK_EE_URGENT_TEMP, 0);
-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-10-25  1:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-25  1:34 [PATCH 0/5] scsi: ufs: Fix device management timeouts and runtime PM errors Stanley Jhu
2026-10-25  1:34 ` [PATCH 1/5] scsi: ufs: core: Restore jiffies conversion of device management timeouts Stanley Jhu
2026-10-25  1:34 ` [PATCH 2/5] scsi: ufs: core: Introduce ufshcd_rpm_resume_and_get() helper Stanley Jhu
2026-10-25  1:34 ` [PATCH 3/5] scsi: ufs: sysfs: Propagate runtime PM resume errors Stanley Jhu
2026-10-25  1:34 ` [PATCH 4/5] scsi: ufs: bsg: Abort ufs_bsg_request() when runtime resume fails Stanley Jhu
2026-10-25  1:34 ` [PATCH 5/5] scsi: ufs: hwmon, debugfs: Propagate runtime PM resume errors Stanley Jhu

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®