From patchwork Tue Aug 16 03:23:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Lin X-Patchwork-Id: 9282557 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 0793D607FD for ; Tue, 16 Aug 2016 03:28:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EE14B28D65 for ; Tue, 16 Aug 2016 03:28:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E285A28D68; Tue, 16 Aug 2016 03:28:38 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7E4B428D65 for ; Tue, 16 Aug 2016 03:28:38 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bZV3L-0007ed-Ir; Tue, 16 Aug 2016 03:28:35 +0000 Received: from lucky1.263xmail.com ([211.157.147.130]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bZV3H-0007ZM-O9 for linux-rockchip@lists.infradead.org; Tue, 16 Aug 2016 03:28:33 +0000 Received: from shawn.lin?rock-chips.com (unknown [192.168.167.228]) by lucky1.263xmail.com (Postfix) with SMTP id E81A71EE7C4; Tue, 16 Aug 2016 11:28:00 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 addr_info_check: 0 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTP id 565E63A6; Tue, 16 Aug 2016 11:27:59 +0800 (CST) X-RL-SENDER: shawn.lin@rock-chips.com X-FST-TO: jh80.chung@samsung.com X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: shawn.lin@rock-chips.com X-UNIQUE-TAG: <75003bf0fd1a529a2288c628794f394b> 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 3744Y9DE1Q; Tue, 16 Aug 2016 11:28:01 +0800 (CST) From: Shawn Lin To: Jaehoon Chung Subject: [RFC PATCH] mmc: dw_mmc: avoid race condition of cpu and IDMAC Date: Tue, 16 Aug 2016 11:23:47 +0800 Message-Id: <1471317827-6049-1-git-send-email-shawn.lin@rock-chips.com> X-Mailer: git-send-email 1.8.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160815_202832_159331_4177D825 X-CRM114-Status: UNSURE ( 7.26 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ulf Hansson , Heiko Stuebner , Shawn Lin , Brian Norris , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Anderson , linux-rockchip@lists.infradead.org MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP 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 lowering the bandwidth of bus and aggravating the Qos to make the large numbers of IP fight for the priority. One possible replaceable solution may be alloc dual buff for the desc to avoid it but could still race each other theoretically. Signed-off-by: Shawn Lin --- drivers/mmc/host/dw_mmc.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 32380d5..7b01fab 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -490,6 +490,23 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, length -= desc_len; /* + * OWN bit should be clear by IDMAC after + * finishing transfer. Let's wait for the + * asynchronous operation of IDMAC and cpu + * to make sure that we do not rely on the + * order of Qos of bus and architecture. + * Otherwise we could see a race condition + * here that the former write operation of + * IDMAC(to clear the OWN bit) reach right + * after the later new configuration of desc + * which makes value of desc been covered + * leading to DMA_SUSPEND state as IDMAC fecth + * the wrong desc then. + */ + while ((readl(&desc->des0) & IDMAC_DES0_OWN)) + ; + + /* * Set the OWN bit and disable interrupts * for this descriptor */ @@ -535,6 +552,23 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, length -= desc_len; /* + * OWN bit should be clear by IDMAC after + * finishing transfer. Let's wait for the + * asynchronous operation of IDMAC and cpu + * to make sure that we do not rely on the + * order of Qos of bus and architecture. + * Otherwise we could see a race condition + * here that the former write operation of + * IDMAC(to clear the OWN bit) reach right + * after the later new configuration of desc + * which makes value of desc been covered + * leading to DMA_SUSPEND state as IDMAC fecth + * the wrong desc then. + */ + while ((readl(&desc->des0) & IDMAC_DES0_OWN)) + ; + + /* * Set the OWN bit and disable interrupts * for this descriptor */