* [PATCH] mmc: core: apply a per-command tuning timeout instead of the whole sequence budget
@ 2026-09-16 3:49 Shawn Lin
2026-09-24 7:18 ` Adrian Hunter
0 siblings, 1 reply; 3+ messages in thread
From: Shawn Lin @ 2026-09-16 3:49 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Adrian Hunter, linux-kernel, Shawn Lin
From: Shawn Lin <shawn.lin@linux.dev>
The tuning specs guarantee that a *sequence* of 40 tuning commands
completes within 150 ms, exclusive of any host overhead:
eMMC, JESD84-B51B 6.6.5.1 "Sampling Tuning Sequence for HS200":
"The Device is guaranteed to complete a sequence of 40 times CMD21
executions within 150 ms. This is exclusive of any host overhead."
SD Physical Layer Specification Version 4.00:
"The card shall complete a sequence of 40 times CMD19 executions
in no more than 150ms. The tuning process is normally shorter than
40 executions of CMD19, and therefore should be shorter than
150 ms."
mmc_send_tuning() however applied that 150 ms as the data timeout of
every single CMD19/CMD21, i.e. 40x the per-execution budget implied
by the specs (150 ms / 40 = 3.75 ms of device time, excluding host
overhead).
The data timeout only matters for tuning commands where the device
never returns the tuning block at all; a wrong sampling phase
normally fails fast with a CRC error instead. Waiting 150 ms per
such test makes software phase scanning painfully slow. With
dw_mmc-rockchip HS200 eMMC the TMOUT register saturates at ~112 ms
for the requested 150 ms, and dw_mmc's execute_tuning() scans every
phase of the tuning window, stalling that long on each phase that
misses the window. Multi-second boot slowdowns have been reported[1].
Note that SDHCI hosts are unaffected: sdhci_send_tuning() does not
use mmc_send_tuning() (the hardware generates and checks the tuning
pattern itself) and bounds every tuning command to 50 ms in software
(sdhci.c). The SDHCI variants which scan the tuning phases manually
through mmc_send_tuning() -- sdhci-msm, sdhci-omap, sdhci-tegra,
sdhci-cadence, sdhci-esdhc-imx, sdhci_am654, sdhci-of-k1,
sdhci-of-dwcmshc (CV180x), sdhci-of-bst and the AMD sdhci-pci
variant -- suffer from the same excessive per-command timeout and
benefit from this change as well.
Use 5 ms per tuning command. For reference, the device serves the
tuning block straight out of its SD/MMC IP (no storage access is
involved), so even in the slowest reasonable setup -- a 64-byte
tuning block at 50 MHz over a 4-bit bus -- the block transfer alone
takes ~2.6 us, and a full tuning transaction only a few us of bus
time. 5 ms is ~1.3x the spec-implied per-execution device budget
(150 ms / 40 = 3.75 ms, excluding host overhead), 30x below the
150 ms ceiling, and the reporter verified that tuning keeps passing
with it on dw_mmc-rockchip HS200 eMMC. Even in the worst case where
every tuning command times out, the whole tuning process stays
bounded within a few hundred milliseconds.
This also bounds the cost of runtime re-tuning, not just the tuning
performed at enumeration time.
[1] Link: https://bugzilla.kernel.org/show_bug.cgi?id=221781
Signed-off-by: Shawn Lin <shawn.lin@linux.dev>
---
drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index a952cc8..abcdcf8 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -708,11 +708,33 @@ int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
data.flags = MMC_DATA_READ;
/*
- * According to the tuning specs, Tuning process
- * is normally shorter 40 executions of CMD19,
- * and timeout value should be shorter than 150 ms
+ * JESD84-B51B 6.6.5.1, "Sampling Tuning Sequence for HS200":
+ *
+ * "The Device is guaranteed to complete a sequence of 40 times
+ * CMD21 executions within 150 ms. This is exclusive of any
+ * host overhead."
+ *
+ * SD Physical Layer Specification Version 4.00:
+ *
+ * "The card shall complete a sequence of 40 times CMD19
+ * executions in no more than 150ms. The tuning process is
+ * normally shorter than 40 executions of CMD19, and therefore
+ * should be shorter than 150 ms."
+ *
+ * Both specs bound a *sequence* of 40 tuning commands, i.e. at
+ * most 150/40 ms (3.75 ms) of device time per command, excluding
+ * host overhead. And that is generous: the device serves the
+ * tuning block straight from its SD/MMC IP, no storage access
+ * involved, so the whole transaction is only a few us of bus
+ * time even in the slowest reasonable setup (64 bytes at
+ * 50 MHz, 4-bit takes ~2.6 us). The timeout exists solely to
+ * catch devices which never return the block at all.
+ *
+ * Use 5 ms per command: ~1.3x the spec-implied per-command
+ * budget for host overhead and slower devices, still 30x below
+ * the 150 ms bound.
*/
- data.timeout_ns = 150 * NSEC_PER_MSEC;
+ data.timeout_ns = 5 * NSEC_PER_MSEC;
data.sg = &sg;
data.sg_len = 1;
--
2.7.4
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] mmc: core: apply a per-command tuning timeout instead of the whole sequence budget
2026-09-16 3:49 [PATCH] mmc: core: apply a per-command tuning timeout instead of the whole sequence budget Shawn Lin
@ 2026-09-24 7:18 ` Adrian Hunter
2026-09-24 7:44 ` Shawn Lin
0 siblings, 1 reply; 3+ messages in thread
From: Adrian Hunter @ 2026-09-24 7:18 UTC (permalink / raw)
To: Shawn Lin, Ulf Hansson; +Cc: linux-mmc, linux-kernel, Shawn Lin
On 16/09/2026 06:49, Shawn Lin wrote:
> From: Shawn Lin <shawn.lin@linux.dev>
>
> The tuning specs guarantee that a *sequence* of 40 tuning commands
> completes within 150 ms, exclusive of any host overhead:
>
> eMMC, JESD84-B51B 6.6.5.1 "Sampling Tuning Sequence for HS200":
>
> "The Device is guaranteed to complete a sequence of 40 times CMD21
> executions within 150 ms. This is exclusive of any host overhead."
>
> SD Physical Layer Specification Version 4.00:
>
> "The card shall complete a sequence of 40 times CMD19 executions
> in no more than 150ms. The tuning process is normally shorter than
> 40 executions of CMD19, and therefore should be shorter than
> 150 ms."
>
> mmc_send_tuning() however applied that 150 ms as the data timeout of
> every single CMD19/CMD21, i.e. 40x the per-execution budget implied
> by the specs (150 ms / 40 = 3.75 ms of device time, excluding host
> overhead).
>
> The data timeout only matters for tuning commands where the device
> never returns the tuning block at all; a wrong sampling phase
> normally fails fast with a CRC error instead. Waiting 150 ms per
> such test makes software phase scanning painfully slow. With
> dw_mmc-rockchip HS200 eMMC the TMOUT register saturates at ~112 ms
> for the requested 150 ms, and dw_mmc's execute_tuning() scans every
> phase of the tuning window, stalling that long on each phase that
> misses the window. Multi-second boot slowdowns have been reported[1].
>
> Note that SDHCI hosts are unaffected: sdhci_send_tuning() does not
> use mmc_send_tuning() (the hardware generates and checks the tuning
> pattern itself) and bounds every tuning command to 50 ms in software
> (sdhci.c). The SDHCI variants which scan the tuning phases manually
> through mmc_send_tuning() -- sdhci-msm, sdhci-omap, sdhci-tegra,
> sdhci-cadence, sdhci-esdhc-imx, sdhci_am654, sdhci-of-k1,
> sdhci-of-dwcmshc (CV180x), sdhci-of-bst and the AMD sdhci-pci
> variant -- suffer from the same excessive per-command timeout and
> benefit from this change as well.
>
> Use 5 ms per tuning command. For reference, the device serves the
> tuning block straight out of its SD/MMC IP (no storage access is
> involved), so even in the slowest reasonable setup -- a 64-byte
> tuning block at 50 MHz over a 4-bit bus -- the block transfer alone
> takes ~2.6 us, and a full tuning transaction only a few us of bus
> time. 5 ms is ~1.3x the spec-implied per-execution device budget
> (150 ms / 40 = 3.75 ms, excluding host overhead), 30x below the
> 150 ms ceiling, and the reporter verified that tuning keeps passing
> with it on dw_mmc-rockchip HS200 eMMC. Even in the worst case where
> every tuning command times out, the whole tuning process stays
> bounded within a few hundred milliseconds.
>
> This also bounds the cost of runtime re-tuning, not just the tuning
> performed at enumeration time.
>
> [1] Link: https://bugzilla.kernel.org/show_bug.cgi?id=221781
> Signed-off-by: Shawn Lin <shawn.lin@linux.dev>
> ---
>
> drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++++++++++++++----
> 1 file changed, 26 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
> index a952cc8..abcdcf8 100644
> --- a/drivers/mmc/core/mmc_ops.c
> +++ b/drivers/mmc/core/mmc_ops.c
> @@ -708,11 +708,33 @@ int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
> data.flags = MMC_DATA_READ;
>
> /*
> - * According to the tuning specs, Tuning process
> - * is normally shorter 40 executions of CMD19,
> - * and timeout value should be shorter than 150 ms
> + * JESD84-B51B 6.6.5.1, "Sampling Tuning Sequence for HS200":
> + *
> + * "The Device is guaranteed to complete a sequence of 40 times
> + * CMD21 executions within 150 ms. This is exclusive of any
> + * host overhead."
> + *
> + * SD Physical Layer Specification Version 4.00:
> + *
> + * "The card shall complete a sequence of 40 times CMD19
> + * executions in no more than 150ms. The tuning process is
> + * normally shorter than 40 executions of CMD19, and therefore
> + * should be shorter than 150 ms."
> + *
> + * Both specs bound a *sequence* of 40 tuning commands, i.e. at
> + * most 150/40 ms (3.75 ms) of device time per command, excluding
> + * host overhead. And that is generous: the device serves the
> + * tuning block straight from its SD/MMC IP, no storage access
> + * involved, so the whole transaction is only a few us of bus
> + * time even in the slowest reasonable setup (64 bytes at
> + * 50 MHz, 4-bit takes ~2.6 us). The timeout exists solely to
> + * catch devices which never return the block at all.
> + *
> + * Use 5 ms per command: ~1.3x the spec-implied per-command
> + * budget for host overhead and slower devices, still 30x below
> + * the 150 ms bound.
> */
> - data.timeout_ns = 150 * NSEC_PER_MSEC;
> + data.timeout_ns = 5 * NSEC_PER_MSEC;
Perhaps it is safer to let drivers provide an override value,
either as an mmc_host member or create
mmc_send_tuning_timeout(host, opcode, cmd_error, timeout_ns)
>
> data.sg = &sg;
> data.sg_len = 1;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] mmc: core: apply a per-command tuning timeout instead of the whole sequence budget
2026-09-24 7:18 ` Adrian Hunter
@ 2026-09-24 7:44 ` Shawn Lin
0 siblings, 0 replies; 3+ messages in thread
From: Shawn Lin @ 2026-09-24 7:44 UTC (permalink / raw)
To: Adrian Hunter; +Cc: shawn.lin, linux-mmc, linux-kernel, Shawn Lin, Ulf Hansson
Hi Adrian,
在 2026/09/24 星期四 15:18, Adrian Hunter 写道:
> On 16/09/2026 06:49, Shawn Lin wrote:
>> From: Shawn Lin <shawn.lin@linux.dev>
>>
>> The tuning specs guarantee that a *sequence* of 40 tuning commands
>> completes within 150 ms, exclusive of any host overhead:
>>
>> eMMC, JESD84-B51B 6.6.5.1 "Sampling Tuning Sequence for HS200":
>>
>> "The Device is guaranteed to complete a sequence of 40 times CMD21
>> executions within 150 ms. This is exclusive of any host overhead."
>>
>> SD Physical Layer Specification Version 4.00:
>>
>> "The card shall complete a sequence of 40 times CMD19 executions
>> in no more than 150ms. The tuning process is normally shorter than
>> 40 executions of CMD19, and therefore should be shorter than
>> 150 ms."
>>
>> mmc_send_tuning() however applied that 150 ms as the data timeout of
>> every single CMD19/CMD21, i.e. 40x the per-execution budget implied
>> by the specs (150 ms / 40 = 3.75 ms of device time, excluding host
>> overhead).
>>
>> The data timeout only matters for tuning commands where the device
>> never returns the tuning block at all; a wrong sampling phase
>> normally fails fast with a CRC error instead. Waiting 150 ms per
>> such test makes software phase scanning painfully slow. With
>> dw_mmc-rockchip HS200 eMMC the TMOUT register saturates at ~112 ms
>> for the requested 150 ms, and dw_mmc's execute_tuning() scans every
>> phase of the tuning window, stalling that long on each phase that
>> misses the window. Multi-second boot slowdowns have been reported[1].
>>
>> Note that SDHCI hosts are unaffected: sdhci_send_tuning() does not
>> use mmc_send_tuning() (the hardware generates and checks the tuning
>> pattern itself) and bounds every tuning command to 50 ms in software
>> (sdhci.c). The SDHCI variants which scan the tuning phases manually
>> through mmc_send_tuning() -- sdhci-msm, sdhci-omap, sdhci-tegra,
>> sdhci-cadence, sdhci-esdhc-imx, sdhci_am654, sdhci-of-k1,
>> sdhci-of-dwcmshc (CV180x), sdhci-of-bst and the AMD sdhci-pci
>> variant -- suffer from the same excessive per-command timeout and
>> benefit from this change as well.
>>
>> Use 5 ms per tuning command. For reference, the device serves the
>> tuning block straight out of its SD/MMC IP (no storage access is
>> involved), so even in the slowest reasonable setup -- a 64-byte
>> tuning block at 50 MHz over a 4-bit bus -- the block transfer alone
>> takes ~2.6 us, and a full tuning transaction only a few us of bus
>> time. 5 ms is ~1.3x the spec-implied per-execution device budget
>> (150 ms / 40 = 3.75 ms, excluding host overhead), 30x below the
>> 150 ms ceiling, and the reporter verified that tuning keeps passing
>> with it on dw_mmc-rockchip HS200 eMMC. Even in the worst case where
>> every tuning command times out, the whole tuning process stays
>> bounded within a few hundred milliseconds.
>>
>> This also bounds the cost of runtime re-tuning, not just the tuning
>> performed at enumeration time.
>>
>> [1] Link: https://bugzilla.kernel.org/show_bug.cgi?id=221781
>> Signed-off-by: Shawn Lin <shawn.lin@linux.dev>
>> ---
>>
>> drivers/mmc/core/mmc_ops.c | 30 ++++++++++++++++++++++++++----
>> 1 file changed, 26 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
>> index a952cc8..abcdcf8 100644
>> --- a/drivers/mmc/core/mmc_ops.c
>> +++ b/drivers/mmc/core/mmc_ops.c
>> @@ -708,11 +708,33 @@ int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
>> data.flags = MMC_DATA_READ;
>>
>> /*
>> - * According to the tuning specs, Tuning process
>> - * is normally shorter 40 executions of CMD19,
>> - * and timeout value should be shorter than 150 ms
>> + * JESD84-B51B 6.6.5.1, "Sampling Tuning Sequence for HS200":
>> + *
>> + * "The Device is guaranteed to complete a sequence of 40 times
>> + * CMD21 executions within 150 ms. This is exclusive of any
>> + * host overhead."
>> + *
>> + * SD Physical Layer Specification Version 4.00:
>> + *
>> + * "The card shall complete a sequence of 40 times CMD19
>> + * executions in no more than 150ms. The tuning process is
>> + * normally shorter than 40 executions of CMD19, and therefore
>> + * should be shorter than 150 ms."
>> + *
>> + * Both specs bound a *sequence* of 40 tuning commands, i.e. at
>> + * most 150/40 ms (3.75 ms) of device time per command, excluding
>> + * host overhead. And that is generous: the device serves the
>> + * tuning block straight from its SD/MMC IP, no storage access
>> + * involved, so the whole transaction is only a few us of bus
>> + * time even in the slowest reasonable setup (64 bytes at
>> + * 50 MHz, 4-bit takes ~2.6 us). The timeout exists solely to
>> + * catch devices which never return the block at all.
>> + *
>> + * Use 5 ms per command: ~1.3x the spec-implied per-command
>> + * budget for host overhead and slower devices, still 30x below
>> + * the 150 ms bound.
>> */
>> - data.timeout_ns = 150 * NSEC_PER_MSEC;
>> + data.timeout_ns = 5 * NSEC_PER_MSEC;
>
> Perhaps it is safer to let drivers provide an override value,
> either as an mmc_host member or create
> mmc_send_tuning_timeout(host, opcode, cmd_error, timeout_ns)
>
This is less likely to cause a regression. Nice idea.
I plan to introduce mmc_send_tuning_timeout() in v2 and convert
dw_mmc-rockchip to use it with a smaller timeout. Other platforms
that also care about the overly long per-command timeout can opt
in individually later.
Thanks for the suggestion.
>>
>> data.sg = &sg;
>> data.sg_len = 1;
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-24 7:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-16 3:49 [PATCH] mmc: core: apply a per-command tuning timeout instead of the whole sequence budget Shawn Lin
2026-09-24 7:18 ` Adrian Hunter
2026-09-24 7:44 ` Shawn Lin
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®