Re: [PATCH RFC] mmc: add an option to unlimit erase group count

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 17 December 2013 15:22, Adrian Hunter <adrian.hunter@xxxxxxxxx> wrote:
> On 17/12/13 15:41, Ulf Hansson wrote:
>> On 17 December 2013 14:01, Vladimir Zapolskiy
>> <vladimir_zapolskiy@xxxxxxxxxx> wrote:
>>> On 12/17/13 12:19, Ulf Hansson wrote:
>>>>
>>>> On 17 December 2013 10:46, Vladimir Zapolskiy
>>>> <vladimir_zapolskiy@xxxxxxxxxx>  wrote:
>>>>>
>>>>> This change adds an option to overcome a hardcoded calculation of
>>>>> maximum erase groups to be used for erase/trim/discard operations.
>>>>> This calculation is plainly based on JEDEC spec, which defines
>>>>> too high erase timeout delays in comparison to SDHC data line timeout.
>>>>
>>>>
>>>> Too high? Should they lye about the timeout instead? :-)
>>>>
>>>
>>> I think instead JEDEC should introduce a divider or something similar,
>>> because 300ms x 1M erase groups gives you 83 hours timeout for erase
>>> operation, which is insane to follow.
>>
>> :-)
>>
>>>
>>>
>>>>>
>>>>> JEDEC specification defines quite high erase timeout value for 300ms
>>>>> multiplied by erase group number, and SD Host Controller specification
>>>>> data line timeout may be much less, e.g. (1<<  13) / 52Mhz ~ 160ms.
>>>>>
>>>>>  From perfromance perspective it is desirable that thousands of erase
>>>>> groups are discarded at once, so there is no much sense to limit
>>>>> maximum erase timeout by data line timeout, if a controller handles
>>>>> correctly erase operation without indication of data line timeout.
>>>>>
>>>>> In addition setting of this option allows to erase/trim/discard MMC
>>>>> cards, for which previously it was reported that ioctl(BLKDISCARD) is
>>>>> not supported, because the currently implemented logic assumes that
>>>>> erase/trim/discard is supported only if data line timeout can be set
>>>>> higher than the erase timeout of one erase group.
>>>>>
>>>>> Note, it is possible to change mmc_core.limit_erase_groups after
>>>>> kernel load, but it will have no effect, because mmc block queue
>>>>> setup and timeout calculations are done only once during mmc_core
>>>>> initialization.
>>>>
>>>>
>>>> No, I don't believe this is the correct approach.
>>>
>>>
>>> Let's try to find the correct one.
>>>
>>>
>>>> The timeout you refer to, is not a data line timeout and it is not cmd
>>>> timeout either. The timeout is the busy signalling timeout or in other
>>>> words, the maximum time the card is allowed to stay busy.
>>>
>>>
>>> I refer to DAT0 line timeout:
>>>
>>>     Data Timeout Counter Value
>>>         This value determines the interval by which DAT line
>>>         timeouts are detected.
>>>
>>>     Data Timeout Error
>>>         This bit is set when detecting one of following timeout conditions.
>>>         (1) Busy timeout for R1b,R5b type
>>
>> The above is an interesting feature. I assume it is intended to be
>> used for detecting busy signalling. The R1b response will be received
>> anyway, I suppose or?
>>
>> I guess, the problem boils done to that there are a limitation in the
>> controller of how big timeout you can set. For some commands, like
>> ERASE you will potentially need a bigger timeout than what the
>> controller can support.
>>
>> I think the easiest solution would be for the host to disable Data
>> Timeout Error (busy signalling) for certain commands, like ERASE. Then
>> instead rely on the mmc core layer to poll with CMD13 to make sure the
>> erase operation is completed.
>>
>> Similar how omap_hsmmc is doing for ERASE.
>
> No omap_hsmmc is *not* polling.  It gets a TC interrupt when the busy line
> is no longer asserted.

Thanks for clarifying this, did not know about the TC interrupts.

I should have checked for MMC_CAP_WAIT_WHILE_BUSY, which is set for
omap_hsmmc and indicates exactly this. :-)

>
>>
>> On the other hand, if the controller supports busy signalling in
>> hardware, we should somehow give it provision to use it since it could
>> mean less polling of CMD13. I am thinking of combining
>> MMC_CAP_WAIT_WHILE_BUSY and host->ops->card_busy() in some smart way
>> from __mmc_switch() and from mmc_do_erase(). Not sure how yet. :-)
>>
>>
>>>         (2) Busy timeout after Write CRC status
>>>         (3) Write CRC Status timeout
>>>         (4) Read Data timeout.
>>
>> What controller are you referring to?
>>
>>>
>>>     CMD38 R1b ERASE
>>>
>>>
>>>
>>>> So I would suggest an approach which in the end will remove
>>>> "cmd_timeout_ms" from the mmc_cmd struct, since it should not be
>>>> needed. Additionally I think SDHCI is abusing it.
>>>>
>>>> Instead a timeout should be used while polling the card status
>>>> (CMD13), to make sure the card has completed it's operation as
>>>> expected, typically handled from mmc_do_erase() and __mmc_switch().
>>>
>>>
>>> I think currently set 10 seconds timeout is good enough and shouldn't
>>> be changed.
>>
>> Actually it is today set to 10 minutes. I guess we could have an upper
>> limit, but still we need to have a better calculated time out, don't
>> we?
>>
>> Kind regards
>> Ulf Hansson
>>
>>>
>>> With best wishes,
>>> Vladimir
>>>
>>>
>>>> Kind regards
>>>> Ulf Hansson
>>>>
>>>>
>>>>>
>>>>> Signed-off-by: Vladimir Zapolskiy<vladimir_zapolskiy@xxxxxxxxxx>
>>>>> Cc: Adrian Hunter<adrian.hunter@xxxxxxxxx>
>>>>> ---
>>>>>   drivers/mmc/core/Kconfig |   14 ++++++++++++++
>>>>>   drivers/mmc/core/core.c  |   11 +++++++++++
>>>>>   drivers/mmc/host/sdhci.c |   14 +++++++++++---
>>>>>   include/linux/mmc/host.h |    1 +
>>>>>   4 files changed, 37 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>>>> index 269d072..9ecdde1 100644
>>>>> --- a/drivers/mmc/core/Kconfig
>>>>> +++ b/drivers/mmc/core/Kconfig
>>>>> @@ -26,3 +26,17 @@ config MMC_CLKGATE
>>>>>            support handling this in order for it to be of any use.
>>>>>
>>>>>            If unsure, say N.
>>>>> +
>>>>> +config MMC_UNLIMIT_ERASE_GROUPS
>>>>> +       bool "Assume fast erase/trim/discard operation (EXPERIMENTAL)"
>>>>> +       depends on EXPERIMENTAL
>>>>> +       help
>>>>> +         This option will disable limitation on maximum quantity of
>>>>> +         erase groups to be erased/trimmed/discarded safely without
>>>>> +         getting a timeout on DAT0 line. On old cards enabling of
>>>>> +         this option may be unsafe, but modern eMMC cards are capable
>>>>> +         to complete the operations in reasonable time regardless of
>>>>> +         extremely overestimated timeout for the operations specified
>>>>> +         by JEDEC standard.
>>>>> +
>>>>> +         If unsure, say N.
>>>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>>>> index 57a2b40..40db797 100644
>>>>> --- a/drivers/mmc/core/core.c
>>>>> +++ b/drivers/mmc/core/core.c
>>>>> @@ -81,6 +81,17 @@ MODULE_PARM_DESC(
>>>>>          removable,
>>>>>          "MMC/SD cards are removable and may be removed during suspend");
>>>>>
>>>>> +#ifdef MMC_UNLIMIT_ERASE_GROUPS
>>>>> +bool mmc_limit_erase_groups;
>>>>> +#else
>>>>> +bool mmc_limit_erase_groups = 1;
>>>>> +#endif
>>>>> +EXPORT_SYMBOL(mmc_limit_erase_groups);
>>>>> +module_param_named(limit_erase_groups, mmc_limit_erase_groups, bool,
>>>>> 0644);
>>>>> +MODULE_PARM_DESC(
>>>>> +       limit_erase_groups,
>>>>> +       "Erase group limitation is calculated from host's data line
>>>>> timeout");
>>>>> +
>>>>>   /*
>>>>>    * Internal function. Schedule delayed work in the MMC work queue.
>>>>>    */
>>>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>>>> index bd8a098..541e9af 100644
>>>>> --- a/drivers/mmc/host/sdhci.c
>>>>> +++ b/drivers/mmc/host/sdhci.c
>>>>> @@ -736,8 +736,13 @@ static void sdhci_prepare_data(struct sdhci_host
>>>>> *host, struct mmc_command *cmd)
>>>>>          WARN_ON(host->data);
>>>>>
>>>>>          if (data || (cmd->flags&  MMC_RSP_BUSY)) {
>>>>>
>>>>> -               count = sdhci_calc_timeout(host, cmd);
>>>>> -               sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
>>>>> +               if (cmd->opcode == MMC_ERASE&&  !mmc_limit_erase_groups)
>>>>> {
>>>>>
>>>>> +                       sdhci_mask_irqs(host, SDHCI_INT_TIMEOUT);
>>>>> +               } else {
>>>>> +                       sdhci_unmask_irqs(host, SDHCI_INT_TIMEOUT);
>>>>> +                       count = sdhci_calc_timeout(host, cmd);
>>>>> +                       sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
>>>>> +               }
>>>>>          }
>>>>>
>>>>>          if (!data)
>>>>> @@ -2930,7 +2935,10 @@ int sdhci_add_host(struct sdhci_host *host)
>>>>>          if (host->quirks&  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
>>>>>
>>>>>                  host->timeout_clk = mmc->f_max / 1000;
>>>>>
>>>>> -       mmc->max_discard_to = (1<<  27) / host->timeout_clk;
>>>>> +       if (mmc_limit_erase_groups)
>>>>> +               mmc->max_discard_to = (1<<  27) / host->timeout_clk;
>>>>> +       else
>>>>> +               mmc->max_discard_to = 0;
>>>>>
>>>>>          mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
>>>>>
>>>>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>>>>> index 99f5709..7c93bb8 100644
>>>>> --- a/include/linux/mmc/host.h
>>>>> +++ b/include/linux/mmc/host.h
>>>>> @@ -426,6 +426,7 @@ int mmc_pm_notify(struct notifier_block
>>>>> *notify_block, unsigned long, void *);
>>>>>
>>>>>   /* Module parameter */
>>>>>   extern bool mmc_assume_removable;
>>>>> +extern bool mmc_limit_erase_groups;
>>>>>
>>>>>   static inline int mmc_card_is_removable(struct mmc_host *host)
>>>>>   {
>>>>> --
>>>>> 1.7.10.4
>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux