From: Shawn Lin <shawn.lin@rock-chips.com>
To: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>,
linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org,
Doug Anderson <dianders@chromium.org>,
Brian Norris <briannorris@chromium.org>,
Heiko Stuebner <heiko@sntech.de>,
linux-rockchip@lists.infradead.org,
Shawn Lin <shawn.lin@rock-chips.com>
Subject: [PATCH 2/2] mmc: dw_mmc: avoid race condition of cpu and IDMAC
Date: Fri, 19 Aug 2016 17:40:15 +0800 [thread overview]
Message-ID: <1471599615-6249-2-git-send-email-shawn.lin@rock-chips.com> (raw)
In-Reply-To: <1471599615-6249-1-git-send-email-shawn.lin@rock-chips.com>
We could see an obvious race condition by test that
the former write operation by IDMAC aiming to clear
OWN bit reach right after the later configuration of
the same desc, which makes the IDMAC be in SUSPEND
state as the OWN bit was cleared by the asynchronous
write operation of IDMAC. The bug can be very easy
reproduced on RK3288 or similar when we reduce the
running rate of system buses and keep the CPU running
faster. So as two separate masters, IDMAC and cpu
write the same descriptor stored on the same address,
and this should be protected by adding check of OWN
bit before preparing new descriptors.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0a5a49f..e640f83 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -473,6 +473,7 @@ static inline void dw_mci_prepare_desc64(struct dw_mci *host,
{
unsigned int desc_len;
struct idmac_desc_64addr *desc_first, *desc_last, *desc;
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
int i;
desc_first = desc_last = desc = host->sg_cpu;
@@ -489,6 +490,20 @@ static inline void dw_mci_prepare_desc64(struct dw_mci *host,
length -= desc_len;
/*
+ * Wait for the former clear OWN bit operation
+ * of IDMAC to make sure that this descriptor
+ * isn't still owned by IDMAC as IDMAC's write
+ * ops and CPU's read ops are asynchronous.
+ */
+ while (readl(&desc->des0) & IDMAC_DES0_OWN) {
+ if (time_after(jiffies, timeout)) {
+ dev_err(host->dev, "DESC is still owned by IDMAC.\n");
+ break;
+ }
+ udelay(10);
+ }
+
+ /*
* Set the OWN bit and disable interrupts
* for this descriptor
*/
@@ -525,6 +540,7 @@ static inline void dw_mci_prepare_desc32(struct dw_mci *host,
{
unsigned int desc_len;
struct idmac_desc *desc_first, *desc_last, *desc;
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
int i;
desc_first = desc_last = desc = host->sg_cpu;
@@ -541,6 +557,20 @@ static inline void dw_mci_prepare_desc32(struct dw_mci *host,
length -= desc_len;
/*
+ * Wait for the former clear OWN bit operation
+ * of IDMAC to make sure that this descriptor
+ * isn't still owned by IDMAC as IDMAC's write
+ * ops and CPU's read ops are asynchronous.
+ */
+ while (readl(&desc->des0) & IDMAC_DES0_OWN) {
+ if (time_after(jiffies, timeout)) {
+ dev_err(host->dev, "DESC is still owned by IDMAC.\n");
+ break;
+ }
+ udelay(10);
+ }
+
+ /*
* Set the OWN bit and disable interrupts
* for this descriptor
*/
--
2.3.7
next prev parent reply other threads:[~2016-08-19 9:56 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20160819095620epcas1p28ffdabf62af8d6e3c01941fde8c8b96b@epcas1p2.samsung.com>
2016-08-19 9:40 ` [PATCH 1/2] mmc: dw_mmc: split out preparation of desc for IDMAC32 and IDMAC64 Shawn Lin
2016-08-19 9:40 ` Shawn Lin [this message]
2016-08-31 6:58 ` [PATCH 2/2] mmc: dw_mmc: avoid race condition of cpu and IDMAC Jaehoon Chung
2016-08-31 7:36 ` Shawn Lin
2016-08-31 6:55 ` [PATCH 1/2] mmc: dw_mmc: split out preparation of desc for IDMAC32 and IDMAC64 Jaehoon Chung
2016-08-31 7:17 ` Shawn Lin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1471599615-6249-2-git-send-email-shawn.lin@rock-chips.com \
--to=shawn.lin@rock-chips.com \
--cc=briannorris@chromium.org \
--cc=dianders@chromium.org \
--cc=heiko@sntech.de \
--cc=jh80.chung@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=ulf.hansson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®