mkfs.ext4 will erase the entire partition on the eMMC device before writing the actual filesystem. The number of blocks erased on each erase eMMC command is determined at run time based on the max erase or trim time specified by the EXT_CSD in the eMMC device and the max eMMC command timeout supported by the host controller. The routine in the kernel that calculates the max number of blocks specified per command returns 1 with some combinations of host controllers with a short max command timeout and eMMC devices with long max erase or trim time. This will end up requiring over 8 million erase sequences on a 4GB eMMC partition and will take many hours. For example, on a host controller with a 50MHz timeout clock specified in the Host CAPS register and an eMMC device with a TRIM Multiplier of 6 specified in the EXT_CSD we get 2^27/50000000=2.68 secs for a max command timeout and 6*.300=1.8 secs for a trim operation which only allows 1 per trim command. The problem seems to be in mmc_do_calc_max_discard() which does it's calculations based on erase blocks but converts to and returns write blocks (2MB blocks to 512 bytes blocks for a typical eMMC device) unless the value is 1 in which case it just returns the 1. The routine also subtracts 1 from the max calculation before converting from erase to write blocks which should not be needed. This change will convert all non-zero max calculations from erase to write blocks and will no longer subtract 1 from the erase block max before converting to write blocks. This allow mkfs.ext4 to run in 30 secs instead of >10 hours. Signed-off-by: Al Cooper <alcooperx@xxxxxxxxx> --- drivers/mmc/core/core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 23f10f7..1b61ac0 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2231,16 +2231,13 @@ static unsigned int mmc_do_calc_max_discard(struct mmc_card *card, if (!qty) return 0; - if (qty == 1) - return 1; - /* Convert qty to sectors */ if (card->erase_shift) - max_discard = --qty << card->erase_shift; + max_discard = qty << card->erase_shift; else if (mmc_card_sd(card)) max_discard = qty; else - max_discard = --qty * card->erase_size; + max_discard = qty * card->erase_size; return max_discard; } -- 1.9.0.138.g2de3478 -- 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