* [PATCH 1/4] scsi: ufs: Reduce the clock scaling latency
2022-04-27 23:38 [PATCH 0/4] Prepare for upstreaming Pixel 6 UFS support Bart Van Assche
@ 2022-04-27 23:38 ` Bart Van Assche
2022-04-28 7:09 ` Avri Altman
2022-04-27 23:38 ` [PATCH 2/4] scsi: ufs: Move a clock scaling check Bart Van Assche
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Bart Van Assche @ 2022-04-27 23:38 UTC (permalink / raw)
To: Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi, Bart Van Assche
Wait at most 20 ms before rechecking the doorbells instead of waiting
for a potentially long time between doorbell checks.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ufs/ufshcd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2b4390a1106e..a3fecbb403d3 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1141,7 +1141,7 @@ static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba,
}
spin_unlock_irqrestore(hba->host->host_lock, flags);
- schedule();
+ io_schedule_timeout(msecs_to_jiffies(20));
if (ktime_to_us(ktime_sub(ktime_get(), start)) >
wait_timeout_us) {
timeout = true;
^ permalink raw reply related [flat|nested] 11+ messages in thread
* RE: [PATCH 1/4] scsi: ufs: Reduce the clock scaling latency
2022-04-27 23:38 ` [PATCH 1/4] scsi: ufs: Reduce the clock scaling latency Bart Van Assche
@ 2022-04-28 7:09 ` Avri Altman
2022-04-28 20:13 ` Bart Van Assche
0 siblings, 1 reply; 11+ messages in thread
From: Avri Altman @ 2022-04-28 7:09 UTC (permalink / raw)
To: Bart Van Assche, Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi
> Wait at most 20 ms before rechecking the doorbells instead of waiting
> for a potentially long time between doorbell checks.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
Nit:
An upper bound of 20msec seems reasonable.
Maybe we should create some linkage to DOORBELL_CLR_TOUT_US?
> ---
> drivers/scsi/ufs/ufshcd.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 2b4390a1106e..a3fecbb403d3 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1141,7 +1141,7 @@ static int ufshcd_wait_for_doorbell_clr(struct
> ufs_hba *hba,
> }
>
> spin_unlock_irqrestore(hba->host->host_lock, flags);
> - schedule();
> + io_schedule_timeout(msecs_to_jiffies(20));
> if (ktime_to_us(ktime_sub(ktime_get(), start)) >
> wait_timeout_us) {
> timeout = true;
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] scsi: ufs: Reduce the clock scaling latency
2022-04-28 7:09 ` Avri Altman
@ 2022-04-28 20:13 ` Bart Van Assche
2022-04-29 5:44 ` Avri Altman
0 siblings, 1 reply; 11+ messages in thread
From: Bart Van Assche @ 2022-04-28 20:13 UTC (permalink / raw)
To: Avri Altman, Martin K . Petersen; +Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi
On 4/28/22 00:09, Avri Altman wrote:
> Maybe we should create some linkage to DOORBELL_CLR_TOUT_US?
Hi Avri,
Do you perhaps want me to change
io_schedule_timeout(msecs_to_jiffies(20));
into something like the following?
io_schedule_timeout(msecs_to_jiffies(min(20, remaining_time)));
Documenting that wait_timeout_us may be exceeded by 20 ms seems like the
easier solution to me :-)
Thanks,
Bart.
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH 1/4] scsi: ufs: Reduce the clock scaling latency
2022-04-28 20:13 ` Bart Van Assche
@ 2022-04-29 5:44 ` Avri Altman
0 siblings, 0 replies; 11+ messages in thread
From: Avri Altman @ 2022-04-29 5:44 UTC (permalink / raw)
To: Bart Van Assche, Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi
> On 4/28/22 00:09, Avri Altman wrote:
> > Maybe we should create some linkage to DOORBELL_CLR_TOUT_US?
>
> Hi Avri,
>
> Do you perhaps want me to change
>
> io_schedule_timeout(msecs_to_jiffies(20));
>
> into something like the following?
>
> io_schedule_timeout(msecs_to_jiffies(min(20, remaining_time)));
>
> Documenting that wait_timeout_us may be exceeded by 20 ms seems like
> the
> easier solution to me :-)
I meant some fraction of DOORBELL_CLR_TOUT_US but that's fine -
It is going away anyway.
Thanks,
Avri
>
> Thanks,
>
> Bart.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/4] scsi: ufs: Move a clock scaling check
2022-04-27 23:38 [PATCH 0/4] Prepare for upstreaming Pixel 6 UFS support Bart Van Assche
2022-04-27 23:38 ` [PATCH 1/4] scsi: ufs: Reduce the clock scaling latency Bart Van Assche
@ 2022-04-27 23:38 ` Bart Van Assche
2022-04-28 7:38 ` Avri Altman
2022-04-27 23:38 ` [PATCH 3/4] scsi: ufs: Pass the clock scaling timeout as an argument Bart Van Assche
2022-04-27 23:38 ` [PATCH 4/4] scsi: ufs: Add suspend/resume SCSI command processing support Bart Van Assche
3 siblings, 1 reply; 11+ messages in thread
From: Bart Van Assche @ 2022-04-27 23:38 UTC (permalink / raw)
To: Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi, Bart Van Assche
Move a check related to clock scaling into ufshcd_devfreq_scale(). This
patch prepares for adding a second ufshcd_clock_scaling_prepare()
caller.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ufs/ufshcd.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a3fecbb403d3..3c83f4049031 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1223,8 +1223,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
ufshcd_scsi_block_requests(hba);
down_write(&hba->clk_scaling_lock);
- if (!hba->clk_scaling.is_allowed ||
- ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
+ if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
ret = -EBUSY;
up_write(&hba->clk_scaling_lock);
ufshcd_scsi_unblock_requests(hba);
@@ -1262,10 +1261,18 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
int ret = 0;
bool is_writelock = true;
+ if (!hba->clk_scaling.is_allowed)
+ return -EBUSY;
+
ret = ufshcd_clock_scaling_prepare(hba);
if (ret)
return ret;
+ if (!hba->clk_scaling.is_allowed) {
+ ret = -EBUSY;
+ goto out_unprepare;
+ }
+
/* scale down the gear before scaling down clocks */
if (!scale_up) {
ret = ufshcd_scale_gear(hba, false);
^ permalink raw reply related [flat|nested] 11+ messages in thread
* RE: [PATCH 2/4] scsi: ufs: Move a clock scaling check
2022-04-27 23:38 ` [PATCH 2/4] scsi: ufs: Move a clock scaling check Bart Van Assche
@ 2022-04-28 7:38 ` Avri Altman
2022-04-28 20:15 ` Bart Van Assche
0 siblings, 1 reply; 11+ messages in thread
From: Avri Altman @ 2022-04-28 7:38 UTC (permalink / raw)
To: Bart Van Assche, Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi
>
> Move a check related to clock scaling into ufshcd_devfreq_scale(). This
> patch prepares for adding a second ufshcd_clock_scaling_prepare()
> caller.
A caller for ufshcd_clock_scaling_prepare() in which clk_scaling is not allowed ?
Thanks,
Avri
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
> drivers/scsi/ufs/ufshcd.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index a3fecbb403d3..3c83f4049031 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1223,8 +1223,7 @@ static int ufshcd_clock_scaling_prepare(struct
> ufs_hba *hba)
> ufshcd_scsi_block_requests(hba);
> down_write(&hba->clk_scaling_lock);
>
> - if (!hba->clk_scaling.is_allowed ||
> - ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
> + if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
> ret = -EBUSY;
> up_write(&hba->clk_scaling_lock);
> ufshcd_scsi_unblock_requests(hba);
> @@ -1262,10 +1261,18 @@ static int ufshcd_devfreq_scale(struct ufs_hba
> *hba, bool scale_up)
> int ret = 0;
> bool is_writelock = true;
>
> + if (!hba->clk_scaling.is_allowed)
> + return -EBUSY;
> +
> ret = ufshcd_clock_scaling_prepare(hba);
> if (ret)
> return ret;
>
> + if (!hba->clk_scaling.is_allowed) {
> + ret = -EBUSY;
> + goto out_unprepare;
> + }
> +
> /* scale down the gear before scaling down clocks */
> if (!scale_up) {
> ret = ufshcd_scale_gear(hba, false);
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/4] scsi: ufs: Move a clock scaling check
2022-04-28 7:38 ` Avri Altman
@ 2022-04-28 20:15 ` Bart Van Assche
0 siblings, 0 replies; 11+ messages in thread
From: Bart Van Assche @ 2022-04-28 20:15 UTC (permalink / raw)
To: Avri Altman, Martin K . Petersen; +Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi
On 4/28/22 00:38, Avri Altman wrote:
>> Move a check related to clock scaling into ufshcd_devfreq_scale(). This
>> patch prepares for adding a second ufshcd_clock_scaling_prepare()
>> caller.
>
> A caller for ufshcd_clock_scaling_prepare() in which clk_scaling is not allowed ?
Hi Avri,
This patch prepares for adding a caller from outside the clock scaling
code path. I will integrate this text in the patch description.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/4] scsi: ufs: Pass the clock scaling timeout as an argument
2022-04-27 23:38 [PATCH 0/4] Prepare for upstreaming Pixel 6 UFS support Bart Van Assche
2022-04-27 23:38 ` [PATCH 1/4] scsi: ufs: Reduce the clock scaling latency Bart Van Assche
2022-04-27 23:38 ` [PATCH 2/4] scsi: ufs: Move a clock scaling check Bart Van Assche
@ 2022-04-27 23:38 ` Bart Van Assche
2022-04-28 7:16 ` Avri Altman
2022-04-27 23:38 ` [PATCH 4/4] scsi: ufs: Add suspend/resume SCSI command processing support Bart Van Assche
3 siblings, 1 reply; 11+ messages in thread
From: Bart Van Assche @ 2022-04-27 23:38 UTC (permalink / raw)
To: Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi, Bart Van Assche
Prepare for adding an additional ufshcd_clock_scaling_prepare() call
with a different timeout.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ufs/ufshcd.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 3c83f4049031..60ba11b68735 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1108,6 +1108,12 @@ static u32 ufshcd_pending_cmds(struct ufs_hba *hba)
return pending;
}
+/*
+ * Wait until all pending SCSI commands and TMFs have finished or the timeout
+ * has expired.
+ *
+ * Return: 0 upon success; -EBUSY upon timeout.
+ */
static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba,
u64 wait_timeout_us)
{
@@ -1212,9 +1218,14 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
return ret;
}
-static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
+/*
+ * Wait until all pending SCSI commands and TMFs have finished or the timeout
+ * has expired.
+ *
+ * Return: 0 upon success; -EBUSY upon timeout.
+ */
+static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
{
- #define DOORBELL_CLR_TOUT_US (1000 * 1000) /* 1 sec */
int ret = 0;
/*
* make sure that there are no outstanding requests when
@@ -1223,7 +1234,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
ufshcd_scsi_block_requests(hba);
down_write(&hba->clk_scaling_lock);
- if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
+ if (ufshcd_wait_for_doorbell_clr(hba, timeout_us)) {
ret = -EBUSY;
up_write(&hba->clk_scaling_lock);
ufshcd_scsi_unblock_requests(hba);
@@ -1264,7 +1275,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
if (!hba->clk_scaling.is_allowed)
return -EBUSY;
- ret = ufshcd_clock_scaling_prepare(hba);
+ ret = ufshcd_clock_scaling_prepare(hba, 1 * USEC_PER_SEC);
if (ret)
return ret;
^ permalink raw reply related [flat|nested] 11+ messages in thread
* RE: [PATCH 3/4] scsi: ufs: Pass the clock scaling timeout as an argument
2022-04-27 23:38 ` [PATCH 3/4] scsi: ufs: Pass the clock scaling timeout as an argument Bart Van Assche
@ 2022-04-28 7:16 ` Avri Altman
0 siblings, 0 replies; 11+ messages in thread
From: Avri Altman @ 2022-04-28 7:16 UTC (permalink / raw)
To: Bart Van Assche, Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi
> Prepare for adding an additional ufshcd_clock_scaling_prepare() call
> with a different timeout.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
> ---
> drivers/scsi/ufs/ufshcd.c | 19 +++++++++++++++----
> 1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 3c83f4049031..60ba11b68735 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1108,6 +1108,12 @@ static u32 ufshcd_pending_cmds(struct ufs_hba
> *hba)
> return pending;
> }
>
> +/*
> + * Wait until all pending SCSI commands and TMFs have finished or the
> timeout
> + * has expired.
> + *
> + * Return: 0 upon success; -EBUSY upon timeout.
> + */
> static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba,
> u64 wait_timeout_us)
> {
> @@ -1212,9 +1218,14 @@ static int ufshcd_scale_gear(struct ufs_hba *hba,
> bool scale_up)
> return ret;
> }
>
> -static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba)
> +/*
> + * Wait until all pending SCSI commands and TMFs have finished or the
> timeout
> + * has expired.
> + *
> + * Return: 0 upon success; -EBUSY upon timeout.
> + */
> +static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64
> timeout_us)
> {
> - #define DOORBELL_CLR_TOUT_US (1000 * 1000) /* 1 sec */
> int ret = 0;
> /*
> * make sure that there are no outstanding requests when
> @@ -1223,7 +1234,7 @@ static int ufshcd_clock_scaling_prepare(struct
> ufs_hba *hba)
> ufshcd_scsi_block_requests(hba);
> down_write(&hba->clk_scaling_lock);
>
> - if (ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) {
> + if (ufshcd_wait_for_doorbell_clr(hba, timeout_us)) {
> ret = -EBUSY;
> up_write(&hba->clk_scaling_lock);
> ufshcd_scsi_unblock_requests(hba);
> @@ -1264,7 +1275,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba,
> bool scale_up)
> if (!hba->clk_scaling.is_allowed)
> return -EBUSY;
>
> - ret = ufshcd_clock_scaling_prepare(hba);
> + ret = ufshcd_clock_scaling_prepare(hba, 1 * USEC_PER_SEC);
> if (ret)
> return ret;
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/4] scsi: ufs: Add suspend/resume SCSI command processing support
2022-04-27 23:38 [PATCH 0/4] Prepare for upstreaming Pixel 6 UFS support Bart Van Assche
` (2 preceding siblings ...)
2022-04-27 23:38 ` [PATCH 3/4] scsi: ufs: Pass the clock scaling timeout as an argument Bart Van Assche
@ 2022-04-27 23:38 ` Bart Van Assche
3 siblings, 0 replies; 11+ messages in thread
From: Bart Van Assche @ 2022-04-27 23:38 UTC (permalink / raw)
To: Martin K . Petersen
Cc: Jaegeuk Kim, Adrian Hunter, linux-scsi, Bart Van Assche
This functionality is needed by UFS drivers to e.g. suspend SCSI command
processing while reprogramming encryption keys if the hardware does not
support concurrent I/O and key reprogramming.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ufs/ufshcd.c | 20 ++++++++++++++++++++
drivers/scsi/ufs/ufshcd.h | 3 +++
2 files changed, 23 insertions(+)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 60ba11b68735..22447c4f16a2 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1692,6 +1692,26 @@ static void ufshcd_ungate_work(struct work_struct *work)
ufshcd_scsi_unblock_requests(hba);
}
+/*
+ * Block processing of new SCSI commands and wait until pending SCSI
+ * commands and TMFs have finished. ufshcd_exec_dev_cmd() and
+ * ufshcd_issue_devman_upiu_cmd() are not affected by this function.
+ *
+ * Return: 0 upon success; -EBUSY upon timeout.
+ */
+int ufshcd_freeze_scsi_devs(struct ufs_hba *hba, u64 timeout_us)
+{
+ return ufshcd_clock_scaling_prepare(hba, timeout_us);
+}
+EXPORT_SYMBOL_GPL(ufshcd_freeze_scsi_devs);
+
+/* Resume processing of SCSI commands. */
+void ufshcd_unfreeze_scsi_devs(struct ufs_hba *hba)
+{
+ ufshcd_clock_scaling_unprepare(hba, true);
+}
+EXPORT_SYMBOL_GPL(ufshcd_unfreeze_scsi_devs);
+
/**
* ufshcd_hold - Enable clocks that were gated earlier due to ufshcd_release.
* Also, exit from hibern8 mode and set the link as active.
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 2b0f3441b813..8954fcbdaf6f 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -1181,6 +1181,9 @@ void ufshcd_release(struct ufs_hba *hba);
void ufshcd_clkgate_delay_set(struct device *dev, unsigned long value);
+int ufshcd_freeze_scsi_devs(struct ufs_hba *hba, u64 timeout_us);
+void ufshcd_unfreeze_scsi_devs(struct ufs_hba *hba);
+
void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,
int *desc_length);
^ permalink raw reply related [flat|nested] 11+ messages in thread