From patchwork Tue Jun 28 07:25:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "\(Exiting\) Baolin Wang" X-Patchwork-Id: 70979 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp1439228qgy; Tue, 28 Jun 2016 00:26:21 -0700 (PDT) X-Received: by 10.66.245.111 with SMTP id xn15mr2471318pac.76.1467098781574; Tue, 28 Jun 2016 00:26:21 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id hh7si32012976pac.33.2016.06.28.00.26.21; Tue, 28 Jun 2016 00:26:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-mmc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-mmc-owner@vger.kernel.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752102AbcF1H0S (ORCPT + 3 others); Tue, 28 Jun 2016 03:26:18 -0400 Received: from mail-pf0-f170.google.com ([209.85.192.170]:33411 "EHLO mail-pf0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751948AbcF1H0P (ORCPT ); Tue, 28 Jun 2016 03:26:15 -0400 Received: by mail-pf0-f170.google.com with SMTP id i123so4043372pfg.0 for ; Tue, 28 Jun 2016 00:26:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=S5cTdLeDL6qJXjS8awjcSMQ7+2hWZbuINBj2hFh0vpw=; b=FwAAoMonRFblbzlISfSAPfCtupxpN3iDaXb0ngmXJzQf41DwyXqxBWtTsSNT9tQXJ8 hf05Cw9b/MzJYxwncY0NbMVeOl7ag1qex7u6Eghb7PP8ALdbfiS1JxVnqbQsEpzXrMQU 7WOIsJxC4AhRIdrDS1Ks5FrtfLoiazA+OGeOU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=S5cTdLeDL6qJXjS8awjcSMQ7+2hWZbuINBj2hFh0vpw=; b=QkIoUpZcA50RzLE/765sukKg7xeAnlzdiydgJztlPJqMWVrZ+a3/BRGSvWdJucIxiN UvtK3qqfkbks1cDwOgHNMZiG8WlARH3VblGKRWJ8j9/wD5uyZDP+6/gIES1Bx+RN51SB bv4FWHSYV39m29rXjEmLDY3+j1l19E6kIOOr/b6RH8HaC1aPQ27ByRfotxArWbGOqx9Z rm1u6FEhVMa8xjYSCtJNDLVEhlrjFgC1VLXuXRi9EildUp66F7j/4c1/+WNSEGmzAX73 zB/0UdKZCCFHRLhEbPu2BfX73s5uG+qtWGyl/0HCOg6LT0bvBxg6imGqFX9914QZ9gZA mjqA== X-Gm-Message-State: ALyK8tJxDkTSV3mQyiia695SVhoCSIJ/do5hFbeOSnrp4ZSttlv4DN+z6Bc5xWAMfGp3hGjT X-Received: by 10.98.62.15 with SMTP id l15mr2480931pfa.24.1467098774230; Tue, 28 Jun 2016 00:26:14 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([175.111.195.49]) by smtp.gmail.com with ESMTPSA id p63sm2253967pfp.65.2016.06.28.00.26.10 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Jun 2016 00:26:13 -0700 (PDT) From: Baolin Wang To: ulf.hansson@linaro.org Cc: adrian.hunter@intel.com, rmk+kernel@arm.linux.org.uk, shawn.lin@rock-chips.com, dianders@chromium.org, heiko@sntech.de, david@protonic.nl, hdegoede@redhat.com, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, broonie@kernel.org, linus.walleij@linaro.org, baolin.wang@linaro.org Subject: [RESEND RFC v2] mmc: Change the max discard sectors and erase response if mmc host supports busy signalling Date: Tue, 28 Jun 2016 15:25:47 +0800 Message-Id: <54f75bccac6e6e49d87a5122ea670038b508b33c.1465808036.git.baolin.wang@linaro.org> X-Mailer: git-send-email 1.7.9.5 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org When mmc host HW supports busy signalling (using R1B as response), We shouldn't use 'host->max_busy_timeout' as the limitation when deciding the max discard sectors that we tell the generic BLOCK layer about. Instead, we should pick one preferred erase size as the max discard sectors. If the host controller supports busy signalling and the timeout for the erase operation does not exceed the max_busy_timeout, we should use R1B response. Or we need to prevent the host from doing hw busy detection, which is done by converting to a R1 response instead. Changes since v1: - Remove the 'MMC_CAP_WAIT_WHILE_BUSY' flag checking when deciding the max discard sectors. Signed-off-by: Baolin Wang --- drivers/mmc/core/core.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8b4dfd4..edd43b1 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2060,7 +2060,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, unsigned int to, unsigned int arg) { struct mmc_command cmd = {0}; - unsigned int qty = 0; + unsigned int qty = 0, busy_timeout = 0; unsigned long timeout; int err; @@ -2128,8 +2128,23 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, memset(&cmd, 0, sizeof(struct mmc_command)); cmd.opcode = MMC_ERASE; cmd.arg = arg; - cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - cmd.busy_timeout = mmc_erase_timeout(card, arg, qty); + busy_timeout = mmc_erase_timeout(card, arg, qty); + /* + * If the host controller supports busy signalling and the timeout for + * the erase operation does not exceed the max_busy_timeout, we should + * use R1B response. Or we need to prevent the host from doing hw busy + * detection, which is done by converting to a R1 response instead. + */ + if ((card->host->max_busy_timeout && + busy_timeout > card->host->max_busy_timeout) || + !(card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)) { + cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; + cmd.busy_timeout = 0; + } else { + cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + cmd.busy_timeout = busy_timeout; + } + err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) { pr_err("mmc_erase: erase error %d, status %#x\n", @@ -2321,23 +2336,39 @@ static unsigned int mmc_do_calc_max_discard(struct mmc_card *card, unsigned int arg) { struct mmc_host *host = card->host; - unsigned int max_discard, x, y, qty = 0, max_qty, timeout; + unsigned int max_discard, x, y, qty = 0, max_qty, min_qty, timeout; unsigned int last_timeout = 0; - if (card->erase_shift) + if (card->erase_shift) { max_qty = UINT_MAX >> card->erase_shift; - else if (mmc_card_sd(card)) + min_qty = card->pref_erase >> card->erase_shift; + } else if (mmc_card_sd(card)) { max_qty = UINT_MAX; - else + min_qty = card->pref_erase; + } else { max_qty = UINT_MAX / card->erase_size; + min_qty = card->pref_erase / card->erase_size; + } /* Find the largest qty with an OK timeout */ do { y = 0; for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) { timeout = mmc_erase_timeout(card, arg, qty + x); - if (timeout > host->max_busy_timeout) + /* + * We should not only use 'host->max_busy_timeout' as + * the limitation when deciding the max discard sectors. + * We should set a balance value to improve the erase + * speed, and it can not get too long timeout at the + * same time. + * + * Here we set 'card->pref_erase' as the minimal discard + * sectors when deciding the max discard sectors. + */ + if (qty + x > min_qty && + timeout > host->max_busy_timeout) break; + if (timeout < last_timeout) break; last_timeout = timeout;