The third iteration of this patch is below. On Wed, May 23, 2018 at 03:50:32PM +0200, Ulf Hansson wrote: > On 22 May 2018 at 18:54, Martin Hicks <mort@xxxxxxxx> wrote: > > 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: > > > > > Even on very quickly completing erase operations, the loop iterates 10+ > > times, so not too much extra latency is added to these commands. > > A comparison between before and after the change would be nice, can > you share those numbers? With this version of the patch, quickly completing commands do 3-4 loops on my hardware. I measured command completion in 0.5-1ms. > > > > 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. > > > > Still, ~1000/s is quite high, especially if it is for doing nothing. :-). This version does about 20 additional interrupts per second. 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 backoff sleep that starts by sleeping for short intervals (128-256us), and ramps up to sleeping for 32-64ms. Even on very quickly completing erase operations, the loop iterates a few 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 about 20/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..4d75107 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=64, udelay_max=32768; 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 *= 2; + } 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