These 3 commits from upstream allow us to have more fine grained control over the MMC command timeouts and this solves the following timeouts that we have seen on our systems across suspend/resume cycles:
[ 14.907496] usb usb2: root hub lost power or was reset [ 15.216232] usb 1-1: reset high-speed USB device number 2 using xhci-hcd [ 15.485812] bcmgenet 8f00000.ethernet eth0: Link is Down [ 15.525328] mmc1: error -110 doing runtime resume [ 15.531864] OOM killer enabled.
Thanks!
Ulf Hansson (3): mmc: core: Specify timeouts for BKOPS and CACHE_FLUSH for eMMC mmc: block: Use generic_cmd6_time when modifying INAND_CMD38_ARG_EXT_CSD mmc: core: Default to generic_cmd6_time as timeout in __mmc_switch()
drivers/mmc/card/block.c | 6 +++--- drivers/mmc/core/core.c | 5 ++++- drivers/mmc/core/mmc_ops.c | 9 +++++---- 3 files changed, 12 insertions(+), 8 deletions(-)
From: Ulf Hansson ulf.hansson@linaro.org
commit 24ed3bd01d6a844fd5e8a75f48d0a3d10ed71bf9 upstream
The timeout values used while waiting for a CMD6 for BKOPS or a CACHE_FLUSH to complete, are not defined by the eMMC spec. However, a timeout of 10 minutes as is currently being used, is just silly for both of these cases. Instead, let's specify more reasonable timeouts, 120s for BKOPS and 30s for CACHE_FLUSH.
Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Link: https://lore.kernel.org/r/20200122142747.5690-2-ulf.hansson@linaro.org Signed-off-by: Kamal Dasu kdasu.kdev@gmail.com [kamal: Drop mmc_run_bkops hunk, non-existent] Signed-off-by: Florian Fainelli f.fainelli@gmail.com --- drivers/mmc/core/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f0fa6a799f7c..dfe55e9d729f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -61,6 +61,8 @@ /* The max erase timeout, used when host->max_busy_timeout isn't specified */ #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */
+#define MMC_CACHE_FLUSH_TIMEOUT_MS (30 * 1000) /* 30s */ + static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
/* @@ -2936,7 +2938,8 @@ int mmc_flush_cache(struct mmc_card *card) (card->ext_csd.cache_size > 0) && (card->ext_csd.cache_ctrl & 1)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_FLUSH_CACHE, 1, 0); + EXT_CSD_FLUSH_CACHE, 1, + MMC_CACHE_FLUSH_TIMEOUT_MS); if (err) pr_err("%s: cache flush error %d\n", mmc_hostname(card->host), err);
From: Ulf Hansson ulf.hansson@linaro.org
commit ad91619aa9d78ab1c6d4a969c3db68bc331ae76c upstream
The INAND_CMD38_ARG_EXT_CSD is a vendor specific EXT_CSD register, which is used to prepare an erase/trim operation. However, it doesn't make sense to use a timeout of 10 minutes while updating the register, which becomes the case when the timeout_ms argument for mmc_switch() is set to zero.
Instead, let's use the generic_cmd6_time, as that seems like a reasonable timeout to use for these cases.
Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Link: https://lore.kernel.org/r/20200122142747.5690-3-ulf.hansson@linaro.org Signed-off-by: Kamal Dasu kdasu.kdev@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com --- drivers/mmc/card/block.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 709a872ed484..7b8c72a07900 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1192,7 +1192,7 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) arg == MMC_TRIM_ARG ? INAND_CMD38_ARG_TRIM : INAND_CMD38_ARG_ERASE, - 0); + card->ext_csd.generic_cmd6_time); if (err) goto out; } @@ -1235,7 +1235,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, arg == MMC_SECURE_TRIM1_ARG ? INAND_CMD38_ARG_SECTRIM1 : INAND_CMD38_ARG_SECERASE, - 0); + card->ext_csd.generic_cmd6_time); if (err) goto out_retry; } @@ -1251,7 +1251,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, INAND_CMD38_ARG_EXT_CSD, INAND_CMD38_ARG_SECTRIM2, - 0); + card->ext_csd.generic_cmd6_time); if (err) goto out_retry; }
From: Ulf Hansson ulf.hansson@linaro.org
commit 533a6cfe08f96a7b5c65e06d20916d552c11b256 upstream
All callers of __mmc_switch() should now be specifying a valid timeout for the CMD6 command. However, just to be sure, let's print a warning and default to use the generic_cmd6_time in case the provided timeout_ms argument is zero.
In this context, let's also simplify some of the corresponding code and clarify some related comments.
Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Link: https://lore.kernel.org/r/20200122142747.5690-4-ulf.hansson@linaro.org Signed-off-by: Kamal Dasu kdasu.kdev@gmail.com [kamal: Drop non-existent hunks in 4.9's __mmc_switch] Signed-off-by: Florian Fainelli f.fainelli@gmail.com --- drivers/mmc/core/mmc_ops.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index ad6e9798e949..3d8907fc2a52 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -22,8 +22,6 @@ #include "host.h" #include "mmc_ops.h"
-#define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ - static const u8 tuning_blk_pattern_4bit[] = { 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, @@ -530,8 +528,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, ignore_crc = false;
/* We have an unspecified cmd timeout, use the fallback value. */ - if (!timeout_ms) - timeout_ms = MMC_OPS_TIMEOUT_MS; + if (!timeout_ms) { + pr_warn("%s: unspecified timeout for CMD6 - use generic\n", + mmc_hostname(host)); + timeout_ms = card->ext_csd.generic_cmd6_time; + }
/* Must check status to be sure of no errors. */ timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1;
linux-stable-mirror@lists.linaro.org