From patchwork Tue Dec 17 09:46:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Zapolskiy X-Patchwork-Id: 3360281 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 10D30C0D4A for ; Tue, 17 Dec 2013 09:46:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B43C920397 for ; Tue, 17 Dec 2013 09:46:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AED252034F for ; Tue, 17 Dec 2013 09:46:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751430Ab3LQJqp (ORCPT ); Tue, 17 Dec 2013 04:46:45 -0500 Received: from relay1.mentorg.com ([192.94.38.131]:46266 "EHLO relay1.mentorg.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751332Ab3LQJqn (ORCPT ); Tue, 17 Dec 2013 04:46:43 -0500 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1VsrEg-0001pR-67 from Vladimir_Zapolskiy@mentor.com ; Tue, 17 Dec 2013 01:46:42 -0800 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Tue, 17 Dec 2013 01:46:42 -0800 Received: from meadow.mgc.mentorg.com (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server (TLS) id 14.2.247.3; Tue, 17 Dec 2013 09:46:39 +0000 From: Vladimir Zapolskiy To: CC: Adrian Hunter Subject: [PATCH RFC] mmc: add an option to unlimit erase group count Date: Tue, 17 Dec 2013 10:46:26 +0100 Message-ID: <1387273586-6839-1-git-send-email-vladimir_zapolskiy@mentor.com> X-Mailer: git-send-email 1.7.10.4 MIME-Version: 1.0 X-Originating-IP: [137.202.0.76] X-OriginalArrivalTime: 17 Dec 2013 09:46:42.0039 (UTC) FILETIME=[E3CD6070:01CEFB0C] Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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. 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. Signed-off-by: Vladimir Zapolskiy Cc: Adrian Hunter --- 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) {