From patchwork Wed Apr 27 09:31:00 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: 8954011 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A18CEBF29F for ; Wed, 27 Apr 2016 09:31:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B563F2024C for ; Wed, 27 Apr 2016 09:31:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A94CE201EF for ; Wed, 27 Apr 2016 09:31:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752589AbcD0Jbi (ORCPT ); Wed, 27 Apr 2016 05:31:38 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:34097 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752346AbcD0Jbg (ORCPT ); Wed, 27 Apr 2016 05:31:36 -0400 Received: by mail-pa0-f50.google.com with SMTP id r5so17414309pag.1 for ; Wed, 27 Apr 2016 02:31:36 -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=YGje/KKH3nQrQcW98ivHkc0xe3oPszDC14a/bx0u3+A=; b=LB6/X4ZR27dYU5QKlIT+9y+0YkwDkdSRFXGqCS55REDMq/hYv4kGDLYe/IiZS7dG8f XHIRWUKG6DkEcxMCCsxr8P6CAyNfniguiG8NLwFmfdMYhagrnsZpbUHmq9AlOs5nYeIy lhnz/U73HsaoIce67b1wvGp/gqSaiL4d8PU3s= 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=YGje/KKH3nQrQcW98ivHkc0xe3oPszDC14a/bx0u3+A=; b=DM8Iy/6EZKXQIM7K4KcAxUjxaF5SPhBaXltpi0SAxVZhSC6xcP0z91jDRPcNwBD0F1 ceKNu1GFwx5rDl32DqxsbiKXBkCXo7S7c4KNjtHoQzkGOhbaxn8p3XstzAz+QLw7axnX bBSb+wF6eA/k3tiG+/S9S668H2RdO1S5csbn6tjyOZA6tMieVd8LiMupL6Rd7521Nk0m 69ngyeNj058U4H6XYfFsph57Rxg/pP6m3sR8vcqlqb8Qhk0k2GchAdpDpLCU8rP0cwl2 e8BT5ymrpug6sGZQGyiYLGWCxjsWrvW76UQ8cOyr5Tsd1Ggf1owoffn+6zrdKGP8uwIY Jb+Q== X-Gm-Message-State: AOPr4FUPeE1mBzlHfUwWbO1I4uze4yx1JrEBDYvTnH63kFz6YmxTpcGf92wo6YR1MEw7I+aw X-Received: by 10.66.141.144 with SMTP id ro16mr10144072pab.137.1461749495525; Wed, 27 Apr 2016 02:31:35 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([175.111.195.49]) by smtp.gmail.com with ESMTPSA id yl5sm4962701pac.38.2016.04.27.02.31.32 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 27 Apr 2016 02:31:34 -0700 (PDT) From: Baolin 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, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, broonie@kernel.org, linus.walleij@linaro.org, baolin.wang@linaro.org Subject: [RFC v2] mmc: Change the max discard sectors and erase response if mmc host supports busy signalling Date: Wed, 27 Apr 2016 17:31:00 +0800 Message-Id: <97683368d0c597ef6311e19233ff864c8e5bb6d9.1461749371.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 X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Baolin Wang 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(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 3f1362a..97935b7 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2008,7 +2008,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; @@ -2076,8 +2076,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", @@ -2269,23 +2284,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;