[PATCH] mmc: core: avoid blocking CPU for long BKOPS

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

 



Since the timeout for a command might be 10 minutes (fallback), don't
eat all CPU power spinning for completion (triggering lockup detector).
Implement delay with exponential backoff and a one second limit.

[158480.011769] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! [fsck.f2fs:962]
[158480.014911] Modules linked in: brcmfmac brcmutil cfg80211 mmc_block sdhci_tegra cqhci sdhci_pltfm sdhci pwrseq_simple pwrseq_emmc mmc_core
[158480.018291] CPU: 3 PID: 962 Comm: fsck.f2fs Not tainted 5.5.0-rc1-next-20191209mq-00173-g716e74177313-dirty #95
[158480.021479] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[158480.024934] PC is at sdhci_card_busy+0x28/0x44 [sdhci]
[158480.028858] LR is at __mmc_switch+0x180/0x330 [mmc_core]
[158480.032449] pc : [<af03b118>]    lr : [<af009fcc>]    psr: 60000013
[158480.036004] sp : e79c9b38  ip : ee01dfd0  fp : 00f23d31
[158480.039339] r10: 00000000  r9 : 0000e020  r8 : b0c04900
[158480.042939] r7 : e763e000  r6 : 00000000  r5 : ee189000  r4 : ee189000
[158480.044909] r3 : f002b600  r2 : af03b0f0  r1 : ee01db00  r0 : 1fe70000
[158480.046857] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[158480.048870] Control: 10c5387d  Table: b76ac04a  DAC: 00000055
[158480.050807] CPU: 3 PID: 962 Comm: fsck.f2fs Not tainted 5.5.0-rc1-next-20191209mq-00173-g716e74177313-dirty #95
[158480.052913] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[...]
[158480.098604] [<b0101ab8>] (__irq_svc) from [<af03b118>] (sdhci_card_busy+0x28/0x44 [sdhci])
[158480.101406] [<af03b118>] (sdhci_card_busy [sdhci]) from [<af009fcc>] (__mmc_switch+0x180/0x330 [mmc_core])
[158480.104348] [<af009fcc>] (__mmc_switch [mmc_core]) from [<af00a3bc>] (mmc_run_bkops+0xdc/0x114 [mmc_core])
[158480.107209] [<af00a3bc>] (mmc_run_bkops [mmc_core]) from [<af067d88>] (mmc_blk_mq_complete_prev_req.part.4+0x8c/0x21c [mmc_block])
[158480.110043] [<af067d88>] (mmc_blk_mq_complete_prev_req.part.4 [mmc_block]) from [<af067f94>] (mmc_blk_rw_wait+0x7c/0x11c [mmc_block])
[158480.112914] [<af067f94>] (mmc_blk_rw_wait [mmc_block]) from [<af068c34>] (mmc_blk_mq_issue_rq+0x318/0x898 [mmc_block])
[158480.115733] [<af068c34>] (mmc_blk_mq_issue_rq [mmc_block]) from [<af069608>] (mmc_mq_queue_rq+0x124/0x244 [mmc_block])
[158480.118466] [<af069608>] (mmc_mq_queue_rq [mmc_block]) from [<b04560b0>] (__blk_mq_try_issue_directly+0x118/0x1a0)
[158480.121200] [<b04560b0>] (__blk_mq_try_issue_directly) from [<b04571c0>] (blk_mq_request_issue_directly+0x40/0x5c)
[158480.123980] [<b04571c0>] (blk_mq_request_issue_directly) from [<b0457228>] (blk_mq_try_issue_list_directly+0x4c/0xc0)
[158480.126780] [<b0457228>] (blk_mq_try_issue_list_directly) from [<b045bc70>] (blk_mq_sched_insert_requests+0x1b0/0x234)
[158480.129601] [<b045bc70>] (blk_mq_sched_insert_requests) from [<b04570a8>] (blk_mq_flush_plug_list+0x318/0x3f0)
[158480.132446] [<b04570a8>] (blk_mq_flush_plug_list) from [<b044bcb0>] (blk_flush_plug_list+0xc0/0xc8)
[158480.135292] [<b044bcb0>] (blk_flush_plug_list) from [<b044bcec>] (blk_finish_plug+0x34/0x4c)
[158480.138113] [<b044bcec>] (blk_finish_plug) from [<b024104c>] (read_pages+0x60/0x150)
[158480.140988] [<b024104c>] (read_pages) from [<b0241338>] (__do_page_cache_readahead+0x1fc/0x20c)
[158480.143893] [<b0241338>] (__do_page_cache_readahead) from [<b02361f8>] (generic_file_read_iter+0x9ac/0xd28)
[158480.146818] [<b02361f8>] (generic_file_read_iter) from [<b02b6920>] (__vfs_read+0x128/0x1a8)
[158480.149695] [<b02b6920>] (__vfs_read) from [<b02b6a34>] (vfs_read+0x94/0x11c)
[158480.152638] [<b02b6a34>] (vfs_read) from [<b02b6d34>] (ksys_read+0x50/0xbc)
[158480.155601] [<b02b6d34>] (ksys_read) from [<b0101000>] (ret_fast_syscall+0x0/0x50)
[158480.158490] Exception stack(0xe79c9fa8 to 0xe79c9ff0)
[158480.161430] 9fa0:                   00000003 01bec3b8 00000003 01bec3b8 00001000 00000000
[158480.164422] 9fc0: 00000003 01bec3b8 00000000 00000003 01bec3b8 01bdf178 a6fc3f70 00000000
[158480.167385] 9fe0: a6f95074 aecadaf8 a6f82c58 a6ef2284

Signed-off-by: Michał Mirosław <mirq-linux@xxxxxxxxxxxx>
---
 drivers/mmc/core/mmc_ops.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 09113b9ad679..e3005e5b9509 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -20,6 +20,7 @@
 #include "mmc_ops.h"
 
 #define MMC_OPS_TIMEOUT_MS	(10 * 60 * 1000) /* 10 minute timeout */
+#define MMC_MAX_POLL_MS		(1000) /* 1 second */
 
 static const u8 tuning_blk_pattern_4bit[] = {
 	0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
@@ -454,6 +455,7 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
 	struct mmc_host *host = card->host;
 	int err;
 	unsigned long timeout;
+	unsigned int wait_ms;
 	u32 status = 0;
 	bool expired = false;
 	bool busy = false;
@@ -473,6 +475,7 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
 	}
 
 	timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1;
+	wait_ms = 1;
 	do {
 		/*
 		 * Due to the possibility of being preempted while polling,
@@ -482,6 +485,11 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
 
 		if (host->ops->card_busy) {
 			busy = host->ops->card_busy(host);
+			if (busy && !expired) {
+				mmc_delay(wait_ms);
+				if (wait_ms < MMC_MAX_POLL_MS)
+					wait_ms *= 2;
+			}
 		} else {
 			err = mmc_send_status(card, &status);
 			if (retry_crc_err && err == -EILSEQ) {
-- 
2.20.1




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

  Powered by Linux