From patchwork Wed May 30 02:12:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Lin X-Patchwork-Id: 10437515 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E18BA602BF for ; Wed, 30 May 2018 02:13:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CFE5328892 for ; Wed, 30 May 2018 02:13:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C478328895; Wed, 30 May 2018 02:13:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,RCVD_IN_SORBS_WEB autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F89A28892 for ; Wed, 30 May 2018 02:13:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754995AbeE3CNH (ORCPT ); Tue, 29 May 2018 22:13:07 -0400 Received: from lucky1.263xmail.com ([211.157.147.133]:44378 "EHLO lucky1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751708AbeE3CNG (ORCPT ); Tue, 29 May 2018 22:13:06 -0400 Received: from shawn.lin?rock-chips.com (unknown [192.168.167.129]) by lucky1.263xmail.com (Postfix) with ESMTP id A911B956E1; Wed, 30 May 2018 10:13:04 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id D439F3AF; Wed, 30 May 2018 10:13:02 +0800 (CST) X-IP-DOMAINF: 1 X-RL-SENDER: shawn.lin@rock-chips.com X-FST-TO: ulf.hansson@linaro.org X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: shawn.lin@rock-chips.com X-UNIQUE-TAG: <715c0bb82ad2019d5ddd5d73cd0b1a86> X-ATTACHMENT-NUM: 0 X-SENDER: lintao@rock-chips.com X-DNS-TYPE: 0 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 6807HXI9GV; Wed, 30 May 2018 10:13:04 +0800 (CST) From: Shawn Lin To: Ulf Hansson Cc: linux-mmc@vger.kernel.org, Martin Hicks , Shawn Lin Subject: [PATCH v3 9/9] mmc: core: Improve system responsiveness when polling for busy Date: Wed, 30 May 2018 10:12:58 +0800 Message-Id: <1527646378-134633-1-git-send-email-shawn.lin@rock-chips.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1527646231-132327-1-git-send-email-shawn.lin@rock-chips.com> References: <1527646231-132327-1-git-send-email-shawn.lin@rock-chips.com> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Previously, we only throttle sending status when doing earse or accessing RPMB. So this patch firstly add a new flag to teach mmc_poll_for_busy() to relinquish CPU for the cases aforementioned, as mmc_poll_for_busy() is also used in performance critical path so that we don't want to hurt performance. However, based on the fact that the system will serve busy polling which could drastically hurt responsiveness if only one online CPU is serving the system. Then there is also an old saying that "Grasp all, lose all", which teach us to sacrifice a little peformance to gain responsiveness in this case. Summary: relinquish CPU in MP system for doing erase and accessing RPMB, or do it for all operations waiting for polling busy when only one CPU is serving for schedule. Signed-off-by: Shawn Lin --- Changes in v3: None Changes in v2: None drivers/mmc/core/block.c | 7 ++++--- drivers/mmc/core/core.c | 2 +- drivers/mmc/core/mmc_ops.c | 25 +++++++++++++++++++++---- drivers/mmc/core/mmc_ops.h | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 4186bc2..da19e0d 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -586,7 +586,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, * "Send Status". */ err = mmc_poll_for_busy(card, 500, true, false, false, NULL, - &mmc_blk_rpmb_in_busy_state, false); + &mmc_blk_rpmb_in_busy_state, false, + true); if (err) /* Convert to -EPERM to avoid possible ABI regression */ err = -EPERM; @@ -1600,7 +1601,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req) mmc_blk_send_stop(card, timeout); err = mmc_poll_for_busy(card, timeout, true, false, false, NULL, - &mmc_blk_in_busy_state, false); + &mmc_blk_in_busy_state, false, false); mmc_retune_release(card->host); @@ -1826,7 +1827,7 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req) return 0; err = mmc_poll_for_busy(card, MMC_BLK_TIMEOUT_MS, true, false, false, - &status, &mmc_blk_in_busy_state, false); + &status, &mmc_blk_in_busy_state, false, false); /* * Do not assume data transferred correctly if there are any error bits diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index d10df43..722150d 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2065,7 +2065,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, } err = mmc_poll_for_busy(card, busy_timeout, true, false, use_r1b_resp, - NULL, &mmc_erase_in_busy_state, false); + NULL, &mmc_erase_in_busy_state, false, true); out: mmc_retune_release(card->host); return err; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 9ff25c6..81e3800 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -454,10 +454,10 @@ int mmc_switch_status(struct mmc_card *card) int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, bool send_status, bool retry_crc_err, bool use_r1b_resp, u32 *resp_status, bool check_busy(u32 device_status), - bool poll_for_switch) + bool poll_for_switch, bool relinquish_cpu) { struct mmc_host *host = card->host; - int err; + int err, loop_udelay=64, udelay_max=32768; unsigned long timeout; u32 status = 0; bool expired = false; @@ -519,7 +519,24 @@ int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, mmc_hostname(host), __func__); return -ETIMEDOUT; } - } while (busy); + + if (!busy) + break; + + /* + * Relinquish CPU unconditionally if the caller wants. + * Or try to do that if only one CPU is online for sched + * which is based on the strategy to balance response time + * with turnaround time. + */ + if (unlikely(relinquish_cpu || num_online_cpus() == 1)) { + usleep_range(loop_udelay, loop_udelay << 1); + if (loop_udelay < udelay_max) + loop_udelay <<= 1; + } + + + } while (1); return 0; } @@ -598,7 +615,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, /* Let's try to poll to find out when the command is completed. */ err = mmc_poll_for_busy(card, timeout_ms, send_status, retry_crc_err, use_r1b_resp, NULL, &mmc_switch_in_prg_state, - true); + true, false); if (err) goto out; diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 8830c1d..4a30a81 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -36,7 +36,7 @@ int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, bool send_status, bool retry_crc_err, bool use_r1b_resp, u32 *resp_status, bool check_busy(u32 device_status), - bool poll_for_switch); + bool poll_for_switch, bool relinquish_cpu); int mmc_switch_status(struct mmc_card *card); int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal); int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,