[PATCH v3 06/12] scsi: ufs: core: Add helpers to pause and resume command processing

Can Guo posted 12 patches 1 month ago
Only 11 patches received!
There is a newer version of this series
[PATCH v3 06/12] scsi: ufs: core: Add helpers to pause and resume command processing
Posted by Can Guo 1 month ago
In preparation for supporting TX Equalization refreshing, introduce
helper functions to safely pause and resume command processing.

ufshcd_pause_command_processing() ensures the host is in a quiescent
state by stopping the block layer tagset, acquiring the necessary
locks (scan_mutex and clk_scaling_lock), and waiting for any
in-flight commands to complete within a specified timeout.

ufshcd_resume_command_processing() restores the host to its previous
operational state by reversing these steps in the correct order.

Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
---
 drivers/ufs/core/ufshcd-priv.h |  2 ++
 drivers/ufs/core/ufshcd.c      | 42 ++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
index 20ec8d8ac0a4..2303d57bf874 100644
--- a/drivers/ufs/core/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -78,6 +78,8 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag);
 int ufshcd_mcq_abort(struct scsi_cmnd *cmd);
 int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag);
 void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct scsi_cmnd *cmd);
+int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us);
+void ufshcd_resume_command_processing(struct ufs_hba *hba);
 
 /**
  * enum ufs_descr_fmt - UFS string descriptor format
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 15543ad03181..6fef24612be1 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -1362,6 +1362,48 @@ static int ufshcd_wait_for_pending_cmds(struct ufs_hba *hba,
 	return ret;
 }
 
+/**
+ * ufshcd_pause_command_processing - Pause command processing
+ * @hba: per-adapter instance
+ * @timeout_us: timeout in microseconds to wait for pending commands to finish
+ *
+ * This function stops new command submissions and waits for existing commands
+ * to complete.
+ *
+ * Return: 0 on success, %-EBUSY if commands did not finish within @timeout_us.
+ * On failure, all acquired locks are released and the tagset is unquiesced.
+ */
+int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
+{
+	int ret = 0;
+
+	mutex_lock(&hba->host->scan_mutex);
+	blk_mq_quiesce_tagset(&hba->host->tag_set);
+	down_write(&hba->clk_scaling_lock);
+
+	if (ufshcd_wait_for_pending_cmds(hba, timeout_us)) {
+		ret = -EBUSY;
+		up_write(&hba->clk_scaling_lock);
+		blk_mq_unquiesce_tagset(&hba->host->tag_set);
+		mutex_unlock(&hba->host->scan_mutex);
+	}
+
+	return ret;
+}
+
+/**
+ * ufshcd_resume_command_processing - Resume command processing
+ * @hba: per-adapter instance
+ *
+ * This function resumes command submissions.
+ */
+void ufshcd_resume_command_processing(struct ufs_hba *hba)
+{
+	up_write(&hba->clk_scaling_lock);
+	blk_mq_unquiesce_tagset(&hba->host->tag_set);
+	mutex_unlock(&hba->host->scan_mutex);
+}
+
 /**
  * ufshcd_scale_gear - scale up/down UFS gear
  * @hba: per adapter instance
-- 
2.34.1
Re: [PATCH v3 06/12] scsi: ufs: core: Add helpers to pause and resume command processing
Posted by Bart Van Assche 3 weeks, 5 days ago
On 3/8/26 8:14 AM, Can Guo wrote:
> +/**
> + * ufshcd_pause_command_processing - Pause command processing
> + * @hba: per-adapter instance
> + * @timeout_us: timeout in microseconds to wait for pending commands to finish
> + *
> + * This function stops new command submissions and waits for existing commands
> + * to complete.
> + *
> + * Return: 0 on success, %-EBUSY if commands did not finish within @timeout_us.
> + * On failure, all acquired locks are released and the tagset is unquiesced.
> + */
> +int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
> +{
> +	int ret = 0;
> +
> +	mutex_lock(&hba->host->scan_mutex);
> +	blk_mq_quiesce_tagset(&hba->host->tag_set);
> +	down_write(&hba->clk_scaling_lock);
> +
> +	if (ufshcd_wait_for_pending_cmds(hba, timeout_us)) {
> +		ret = -EBUSY;
> +		up_write(&hba->clk_scaling_lock);
> +		blk_mq_unquiesce_tagset(&hba->host->tag_set);
> +		mutex_unlock(&hba->host->scan_mutex);
> +	}
> +
> +	return ret;
> +}
> +
> +/**
> + * ufshcd_resume_command_processing - Resume command processing
> + * @hba: per-adapter instance
> + *
> + * This function resumes command submissions.
> + */
> +void ufshcd_resume_command_processing(struct ufs_hba *hba)
> +{
> +	up_write(&hba->clk_scaling_lock);
> +	blk_mq_unquiesce_tagset(&hba->host->tag_set);
> +	mutex_unlock(&hba->host->scan_mutex);
> +}
> +

This patch duplicates existing code. Please integrate the following
changes in this patch:
- ufshcd_clock_scaling_prepare() calls
   ufshcd_pause_command_processing().
- ufshcd_clock_scaling_unprepare() calls
   ufshcd_resume_command_processing().

Thanks,

Bart.
Re: [PATCH v3 06/12] scsi: ufs: core: Add helpers to pause and resume command processing
Posted by Can Guo 3 weeks, 5 days ago
Hi Bart,

On 3/14/2026 6:26 AM, Bart Van Assche wrote:
> On 3/8/26 8:14 AM, Can Guo wrote:
>> +/**
>> + * ufshcd_pause_command_processing - Pause command processing
>> + * @hba: per-adapter instance
>> + * @timeout_us: timeout in microseconds to wait for pending commands 
>> to finish
>> + *
>> + * This function stops new command submissions and waits for 
>> existing commands
>> + * to complete.
>> + *
>> + * Return: 0 on success, %-EBUSY if commands did not finish within 
>> @timeout_us.
>> + * On failure, all acquired locks are released and the tagset is 
>> unquiesced.
>> + */
>> +int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 
>> timeout_us)
>> +{
>> +    int ret = 0;
>> +
>> +    mutex_lock(&hba->host->scan_mutex);
>> +    blk_mq_quiesce_tagset(&hba->host->tag_set);
>> +    down_write(&hba->clk_scaling_lock);
>> +
>> +    if (ufshcd_wait_for_pending_cmds(hba, timeout_us)) {
>> +        ret = -EBUSY;
>> +        up_write(&hba->clk_scaling_lock);
>> +        blk_mq_unquiesce_tagset(&hba->host->tag_set);
>> +        mutex_unlock(&hba->host->scan_mutex);
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>> +/**
>> + * ufshcd_resume_command_processing - Resume command processing
>> + * @hba: per-adapter instance
>> + *
>> + * This function resumes command submissions.
>> + */
>> +void ufshcd_resume_command_processing(struct ufs_hba *hba)
>> +{
>> +    up_write(&hba->clk_scaling_lock);
>> +    blk_mq_unquiesce_tagset(&hba->host->tag_set);
>> +    mutex_unlock(&hba->host->scan_mutex);
>> +}
>> +
>
> This patch duplicates existing code. Please integrate the following
> changes in this patch:
> - ufshcd_clock_scaling_prepare() calls
>   ufshcd_pause_command_processing().
> - ufshcd_clock_scaling_unprepare() calls
>   ufshcd_resume_command_processing().
I looked into ufshcd_clock_scaling_prepare() and 
ufshcd_clock_scaling_unprepare(),
I see they are coupled with Writebooster, wb_mutex and check on 
scaling.is_allowed,
I don't see an easy way of calling ufshcd_pause_command_processing() and
ufshcd_resume_command_processing() from there.

I also checked the history of changes to ufshcd_clock_scaling_prepare() and
ufshcd_clock_scaling_unprepare(), I can see multiple issues, e.g., deadlock,
were reported and fixed. I am not confident at all to make intrusive changes
to the two functions without breaking clock scaling.

Can we do it later as a separate patch and with enough testing conducted?

Thanks,
Can Guo.
>
> Thanks,
>
> Bart.

Re: [PATCH v3 06/12] scsi: ufs: core: Add helpers to pause and resume command processing
Posted by Bart Van Assche 3 weeks, 2 days ago
On 3/14/26 3:38 AM, Can Guo wrote:
> I also checked the history of changes to
> ufshcd_clock_scaling_prepare() and ufshcd_clock_scaling_unprepare(),
> I can see multiple issues, e.g., deadlock, were reported and fixed.
This deadlock fix: ba81043753ff ("scsi: ufs: core: Fix devfreq
deadlocks")? My understanding is that the deadlock was related to
calling ufshcd_wb_toggle() synchronously from ufshcd_devfreq_scale().
Such deadlocks can be avoided by converting a synchronous call into
an asynchronous call (queuing a work item). However, I'm not sure that's
an option in the context of clock scaling?

Thanks,

Bart.
Re: [PATCH v3 06/12] scsi: ufs: core: Add helpers to pause and resume command processing
Posted by Bart Van Assche 3 weeks, 2 days ago
On 3/14/26 3:38 AM, Can Guo wrote:
> Can we do it later as a separate patch and with enough testing conducted?

That sounds good to me.

Thanks,

Bart.