On Mon, May 21, 2018 at 10:22:11AM +0200, Ulf Hansson wrote: > On 18 May 2018 at 17:19, Martin Hicks <mort@xxxxxxxx> wrote: > > > > I now have second thoughts about this change since the same path is used for > > discarding smaller blocks, like if you have "discard" enabled on ext4. > > These discard requests can complete very quickly and we wouldn't want to add > > latency to these commands. It looks like the "quick" discards can complete > > in as little as 50 loops (~1ms), but that would be dependent on the speed of > > the MMC bus, as well as how much work the eMMC drive has to do. > > I fully agree. Several things comes into play, so clearly we needs > something a bit more clever than a fixed timeout value. > > A simplistic approach could be to use a small timeout to start with, > then increase it while iterating the loops. > > Perhaps start by sleeping 128us, then 256, 512, 1024, 2048, 4096. Then > we probably want to stop increasing at some point. Hi Uffe, Good suggestion. I've gone ahead an recreated the patch with a linear backoff. I had concerns that with some faster eMMC buses (I'm only using DDR52), that doubling the timeout each time may not have enough granularity to eliminate unnecessary latency, so I made the backoff linear. The patch follows: This drastically reduces the rate at which the MMC_SEND_STATUS cmd polls for completion of the MMC Erase operation. The patch does this by adding a linear backoff sleep that starts by sleeping for very short periods (32-64us), and ramps up to sleeping for 1-2ms. Even on very quickly completing erase operations, the loop iterates 10+ times, so not too much extra latency is added to these commands. For long running discard operarations, like a full-device secure discard, this change drops the interrupt rates on my single-core NXP I.MX6UL from 45000/s to <1000/s, and greatly improves system responsiveness. Signed-off-by: Martin Hicks <mort@xxxxxxxx> --- drivers/mmc/core/core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index db1bf63..76ef580 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2159,6 +2159,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, unsigned int qty = 0, busy_timeout = 0; bool use_r1b_resp = false; unsigned long timeout; + int loop_udelay=32, udelay_max=1024; int err; mmc_retune_hold(card->host); @@ -2283,9 +2284,15 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, err = -EIO; goto out; } + if ((cmd.resp[0] & R1_READY_FOR_DATA) && + R1_CURRENT_STATE(cmd.resp[0]) != R1_STATE_PRG) + break; + + usleep_range(loop_udelay, loop_udelay*2); + if (loop_udelay < udelay_max) + loop_udelay += 32; + } while (1); - } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || - (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG)); out: mmc_retune_release(card->host); return err; -- 1.9.1 -- Martin Hicks P.Eng. | mort@xxxxxxxx Bork Consulting Inc. | +1 (613) 266-2296 -- 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