Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753641AbbFCIex (ORCPT ); Wed, 3 Jun 2015 04:34:53 -0400 Received: from protonic.xs4all.nl ([83.163.252.89]:19992 "EHLO protonic.xs4all.nl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752910AbbFCIes (ORCPT ); Wed, 3 Jun 2015 04:34:48 -0400 From: David Jander To: Pierre Ossman , Ulf Hansson , Sascha Hauer Cc: Johan Rudholm , Adrian Hunter , Javier Martinez Canillas , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, David Jander Subject: [RFC PATCH] mmc: core: Optimize case for exactly one erase-group budget TRIM Date: Wed, 3 Jun 2015 10:34:29 +0200 Message-Id: <1433320469-29453-1-git-send-email-david@protonic.nl> X-Mailer: git-send-email 2.1.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2800 Lines: 84 In the (not so unlikely) case that the mmc controller timeout budget is enough for exactly one erase-group, the simplification of allowing one sector has an enormous performance penalty. We optimize this special case by introducing a flag that prohibits erase-group boundary crossing, so that we can allow trimming more than one sector at a time. Signed-off-by: David Jander --- drivers/mmc/core/core.c | 21 +++++++++++++++++---- include/linux/mmc/card.h | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 92e7671..6c9611b 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2089,6 +2089,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, unsigned int arg) { unsigned int rem, to = from + nr; + int err; if (!(card->host->caps & MMC_CAP_ERASE) || !(card->csd.cmdclass & CCC_ERASE)) @@ -2139,6 +2140,15 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, /* 'from' and 'to' are inclusive */ to -= 1; + if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && + (from % card->erase_size)) { + rem = card->erase_size - (from % card->erase_size); + err = mmc_do_erase(card, from, from + rem - 1, arg); + from += rem; + if ((err) || (to <= from)) + return err; + } + return mmc_do_erase(card, from, to, arg); } EXPORT_SYMBOL(mmc_erase); @@ -2234,16 +2244,19 @@ static unsigned int mmc_do_calc_max_discard(struct mmc_card *card, if (!qty) return 0; + /* We can only erase one erase group special case */ if (qty == 1) - return 1; + card->eg_boundary = 1; + else + qty--; /* 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; + max_discard = qty + 1; else - max_discard = --qty * card->erase_size; + max_discard = qty * card->erase_size; return max_discard; } diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 19f0175..704b60d 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -282,6 +282,7 @@ struct mmc_card { unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ unsigned int pref_erase; /* in sectors */ + unsigned int eg_boundary; /* don't cross erase-group boundaries */ u8 erased_byte; /* value of erased bytes */ u32 raw_cid[4]; /* raw card CID */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/