Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp3991875pxb; Tue, 25 Jan 2022 00:52:42 -0800 (PST) X-Google-Smtp-Source: ABdhPJxnLXYmXa0REqAzrQMvokvyGZ/ZqBJkmoYMR0tyeYcD0N7ZZdCEBCynD//dacHvgp8SZ3j1 X-Received: by 2002:a17:906:d552:: with SMTP id cr18mr15084720ejc.387.1643100762176; Tue, 25 Jan 2022 00:52:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643100762; cv=none; d=google.com; s=arc-20160816; b=tJlCi17ROYPYn2mnb4KZI0RXBzHmQ66iNoZ2YvpuZ6AOJ+dsP9BDfD/lBqsGcrReXN uUFj7ohOEtSy5+Jxxd7rBgnDpU7Rf8ZUqHVOP8iZz6pFMnqzKPcLmC+s587FdKmvgEln bBlmc4OtLYNLkoLQ8DvdzdyVdgNXjsIgVrRTGYbVb23aJYJ7BOb4hXBmXyWwjph8KuU6 EIcuo81/wIuWtfKvE/TEkNs8AsQLjtOm7kNdYmiVuHTDJCAU3rpy/W6mvGZSjfcvS/Mb Vy7Y+mXsCnFHCE3wgR4oIJnKLFRd/B20c4Grzucdcv0R1ZMd5ex1/eYS7EkbIMjCHxeA W+4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:date:cc:to:from:subject:message-id; bh=73hoX0k+iJqMAjIIc7i/u+bW9JwdBfIEUTbpISp9SHM=; b=OMZ49kfVbufWVbDUjgyr7VTWMZz1OoAm/+rdH0Jqu9pXBhPWMFuPqgqdtlppqqTQr+ 12f1zXpSFENHoHHvtqfN1PXnuzyg5Xq1m8y0YM6GRyNUDbCbPui592QtfIpfN49cDwFS cNHdDUfxmICe5PIjxp1Sf/Zrw7hW/9GNB+tLCxjGm37zZflx7Ye4SuX7wWwhM/0TbX+4 EfOZ11+Qd5oaGhwDRST9aTtPcVugM58PqfBie5TasporzRLelxiW2Wayl4A2fiD4nigL URMdhdhRiqLKA6ZBirxASxhhYGqYdi/jnKJBoH32I5KqeFCIam9eFcytS/k8j5HtYHiJ R+Jg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m17si10881639edd.153.2022.01.25.00.52.18; Tue, 25 Jan 2022 00:52:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mediatek.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1325649AbiAYEnz (ORCPT + 99 others); Mon, 24 Jan 2022 23:43:55 -0500 Received: from mailgw01.mediatek.com ([60.244.123.138]:36520 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1324739AbiAYDdr (ORCPT ); Mon, 24 Jan 2022 22:33:47 -0500 X-UUID: 27967c8e90634ea090afe0d3355cd65b-20220125 X-UUID: 27967c8e90634ea090afe0d3355cd65b-20220125 Received: from mtkcas11.mediatek.inc [(172.21.101.40)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 938173205; Tue, 25 Jan 2022 11:33:37 +0800 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 25 Jan 2022 11:33:35 +0800 Received: from mhfsdcap04 (10.17.3.154) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 25 Jan 2022 11:33:35 +0800 Message-ID: Subject: Re: [PATCH] mmc: mediatek: Add cmd polling mode From: Chaotian Jing To: Derong Liu , Ulf Hansson , Matthias Brugger CC: , , , , , Peng Zhou Date: Tue, 25 Jan 2022 11:33:35 +0800 In-Reply-To: <20220124121814.17452-1-derong.liu@mediatek.com> References: <20220124121814.17452-1-derong.liu@mediatek.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.28.5-0ubuntu0.18.04.2 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 2022-01-24 at 20:18 +0800, Derong Liu wrote: > We found sdcard can gain more read/write performance > when using cmd polling mode instead of interrupt mode, in the > meantime, > there are much more devices have equipped with high frequency cpu, > so it is necessary to support cmd polling mode. > Hi, I think you have not found the root cause of performace drop. if the sdcard read/write performance is 100MB/s, which means that it can complete 512KB of data xfer within 5ms, and if performance drop is 5%, then means that your interrupt mode will take more than 250us. Is it possible to clarify if the interrupt mode really takes 250us? And, if you find that the polling mode is readlly fast then interrupt mode and has no side effect(ie. cpu loading issue), then, We will drop the interrupt mode of waiting response. > Signed-off-by: Derong Liu > --- > drivers/mmc/host/mtk-sd.c | 92 +++++++++++++++++++++++++++++++++++ > ---- > 1 file changed, 83 insertions(+), 9 deletions(-) > > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c > index 65037e1d7723..612f5115ca4b 100644 > --- a/drivers/mmc/host/mtk-sd.c > +++ b/drivers/mmc/host/mtk-sd.c > @@ -465,6 +465,7 @@ struct msdc_host { > bool hs400_tuning; /* hs400 mode online tuning */ > bool internal_cd; /* Use internal card-detect logic */ > bool cqhci; /* support eMMC hw cmdq */ > + bool cmd_polling_mode; /* support cmd polling mode */ > struct msdc_save_para save_para; /* used when gate HCLK */ > struct msdc_tune_para def_tune_para; /* default tune setting */ > struct msdc_tune_para saved_tune_para; /* tune result of > CMD21/CMD19 */ > @@ -1250,6 +1251,63 @@ static inline bool msdc_cmd_is_ready(struct > msdc_host *host, > return true; > } > > +static inline int use_cmd_polling_mode(struct msdc_host *host, > + struct mmc_command *cmd) > +{ > + /* R1B use interrupt mode */ > + return (host->cmd_polling_mode && > + ((mmc_from_priv(host))->caps2 & > MMC_CAP2_NO_SDIO) && > + (mmc_resp_type(cmd) != MMC_RSP_R1B)); > +} > + > +static bool msdc_command_resp_polling(struct msdc_host *host, > + struct mmc_request *mrq, struct mmc_command *cmd, > + unsigned long timeout) > +{ > + bool ret = false; > + unsigned long tmo; > + int events; > + unsigned long flags; > + > + if (!use_cmd_polling_mode(host, cmd)) > + goto exit; > + > +retry: > + tmo = jiffies + timeout; > + while (1) { > + spin_lock_irqsave(&host->lock, flags); why need spin lock ? if there are no SDIO device irq, then there is no race conditon of access MSDC register. > + events = readl(host->base + MSDC_INT); > + if (events & cmd_ints_mask) { > + /* clear all int flag */ > + events &= cmd_ints_mask; > + writel(events, host->base + MSDC_INT); > + spin_unlock_irqrestore(&host->lock, flags); > + break; > + } > + spin_unlock_irqrestore(&host->lock, flags); > + > + if (time_after(jiffies, tmo) && > + ((events & cmd_ints_mask) == 0)) { > + dev_info(host->dev, "[%s]: CMD<%d> > polling_for_completion timeout ARG<0x%.8x>\n", > + __func__, cmd->opcode, cmd->arg); > + ret = msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, > cmd); > + goto exit; > + } > + } > + > + if (cmd) { > + ret = msdc_cmd_done(host, events, mrq, cmd); > + /* if only autocmd23 done, > + * it needs to polling the continue read/write cmd > directly. > + */ > + if (!ret) > + goto retry; > + } > + > +exit: > + return ret; > +} > + > static void msdc_start_command(struct msdc_host *host, > struct mmc_request *mrq, struct mmc_command *cmd) > { > @@ -1273,7 +1331,10 @@ static void msdc_start_command(struct > msdc_host *host, > rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd); > > spin_lock_irqsave(&host->lock, flags); > - sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask); > + if (use_cmd_polling_mode(host, cmd)) > + sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask); > + else > + sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask); > spin_unlock_irqrestore(&host->lock, flags); > > writel(cmd->arg, host->base + SDC_ARG); > @@ -1290,9 +1351,11 @@ static void msdc_cmd_next(struct msdc_host > *host, > host->hs400_tuning))) || > (mrq->sbc && mrq->sbc->error)) > msdc_request_done(host, mrq); > - else if (cmd == mrq->sbc) > + else if (cmd == mrq->sbc) { > msdc_start_command(host, mrq, mrq->cmd); > - else if (!cmd->data) > + msdc_command_resp_polling(host, mrq, > + mrq->cmd, CMD_TIMEOUT); > + } else if (!cmd->data) > msdc_request_done(host, mrq); > else > msdc_start_data(host, cmd, cmd->data); > @@ -1314,10 +1377,15 @@ static void msdc_ops_request(struct mmc_host > *mmc, struct mmc_request *mrq) > * use HW option, otherwise use SW option > */ > if (mrq->sbc && (!mmc_card_mmc(mmc->card) || > - (mrq->sbc->arg & 0xFFFF0000))) > + (mrq->sbc->arg & 0xFFFF0000))) { > msdc_start_command(host, mrq, mrq->sbc); > - else > + msdc_command_resp_polling(host, mrq, > + mrq->sbc, CMD_TIMEOUT); > + } else { > msdc_start_command(host, mrq, mrq->cmd); > + msdc_command_resp_polling(host, mrq, > + mrq->cmd, CMD_TIMEOUT); > + } > } > > static void msdc_pre_req(struct mmc_host *mmc, struct mmc_request > *mrq) > @@ -1350,9 +1418,11 @@ static void msdc_post_req(struct mmc_host > *mmc, struct mmc_request *mrq, > static void msdc_data_xfer_next(struct msdc_host *host, struct > mmc_request *mrq) > { > if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop- > >error && > - !mrq->sbc) > + !mrq->sbc) { > msdc_start_command(host, mrq, mrq->stop); > - else > + msdc_command_resp_polling(host, mrq, > + mrq->stop, CMD_TIMEOUT); > + } else > msdc_request_done(host, mrq); > } > > @@ -2492,11 +2562,15 @@ static void msdc_of_property_parse(struct > platform_device *pdev, > else > host->hs400_cmd_resp_sel_rising = false; > > - if (of_property_read_bool(pdev->dev.of_node, > - "supports-cqe")) > + if (of_property_read_bool(pdev->dev.of_node, "supports-cqe")) > host->cqhci = true; > else > host->cqhci = false; > + > + if (of_property_read_bool(pdev->dev.of_node, "mediatek,cmd- > polling-mode")) > + host->cmd_polling_mode = true; > + else > + host->cmd_polling_mode = false; > } > > static int msdc_of_clock_parse(struct platform_device *pdev,