From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA296C43331 for ; Tue, 12 Nov 2019 13:03:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C09C02084E for ; Tue, 12 Nov 2019 13:03:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727186AbfKLNC7 (ORCPT ); Tue, 12 Nov 2019 08:02:59 -0500 Received: from smtp2.axis.com ([195.60.68.18]:58741 "EHLO smtp2.axis.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725847AbfKLNC7 (ORCPT ); Tue, 12 Nov 2019 08:02:59 -0500 IronPort-SDR: +v4yHbmv8wg5r4Nll65SWyYY7rw7sYmaq+540BFCcptQQI+X8o5Lf5m+gL9L5NgI8urgqp4tgV Sm1z579RAtph5YM11zTs7eNyeE+I5fSHT/S3mTRPbJEsYPPkF79hP7y6JBFyDur+Tw7fY80YhU 6HrGb4R+9dQzujnSmNb9uD+nkfmJwK1y4Wc6tRop07GJ7HsdlaCZof43Nn2upDx46iCebYt/Wl zdFMHgIQSkK7o3VdMjdQDuuK8HqGtwY//ON+EXbwGqv1vvEL62pQsT/9Aq3Geu2wOjflIFEc1J RAU= X-IronPort-AV: E=Sophos;i="5.68,296,1569276000"; d="scan'208";a="2339766" X-Axis-User: NO X-Axis-NonUser: YES X-Virus-Scanned: Debian amavisd-new at bes.se.axis.com From: Vincent Whitchurch To: torvalds@linux-foundation.org Cc: axboe@kernel.dk, linux@armlinux.org.uk, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, will@kernel.org, catalin.marinas@arm.com, Vincent Whitchurch Subject: [PATCH v2] buffer: Fix I/O error due to ARM read-after-read hazard Date: Tue, 12 Nov 2019 14:02:44 +0100 Message-Id: <20191112130244.16630-1-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.20.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On my dual-core ARM Cortex-A9, reading from squashfs (over dm-verity/ubi/mtd) in a loop for hundreds of hours invariably results in a read failure in squashfs_read_data(). The errors occur because the buffer_uptodate() check fails after wait_on_buffer(). Further debugging shows that the bh was in fact uptodate and that there is no actual I/O error in the lower layers. The problem is caused by the read-after-read hazards in the ARM Cortex-A9 MPCore (erratum #761319, see [1]). The code generated by the compiler for the combination of the wait_on_buffer() and buffer_uptodate() calls reads the flags value twice from memory (see the excerpt of the assembly below). The new value of the BH_Lock flag is seen but the new value of BH_Uptodate is not even though both the bits are read from the same memory location. 27c: 9d08 ldr r5, [sp, #32] 27e: 2400 movs r4, #0 280: e006 b.n 290 282: 6803 ldr r3, [r0, #0] 284: 07da lsls r2, r3, #31 286: f140 810d bpl.w 4a4 28a: 3401 adds r4, #1 28c: 42bc cmp r4, r7 28e: da08 bge.n 2a2 290: f855 0f04 ldr.w r0, [r5, #4]! 294: 6803 ldr r3, [r0, #0] 296: 0759 lsls r1, r3, #29 298: d5f3 bpl.n 282 29a: f7ff fffe bl 0 <__wait_on_buffer> Work around this problem by adding a DMB between the two reads of bh->flags, as recommended in the ARM document. With this barrier, no failures have been seen in more than 5000 hours of the same test. [1] http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a/UAN0004A_a9_read_read.pdf Signed-off-by: Vincent Whitchurch --- v2: Reword commit message. include/linux/buffer_head.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 7b73ef7f902d..4ef909a91f8c 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -352,6 +352,14 @@ static inline void wait_on_buffer(struct buffer_head *bh) might_sleep(); if (buffer_locked(bh)) __wait_on_buffer(bh); + +#ifdef CONFIG_ARM + /* + * Work around ARM Cortex-A9 MPcore Read-after-Read Hazards (erratum + * 761319). + */ + smp_rmb(); +#endif } static inline int trylock_buffer(struct buffer_head *bh) -- 2.20.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90071C17440 for ; Tue, 12 Nov 2019 13:03:06 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 61C9E214E0 for ; Tue, 12 Nov 2019 13:03:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="frXzlH15" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 61C9E214E0 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=axis.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=RYqp7j5KefdyJCLi6Yoz9aCsqThDOJNFkLA5sHv9wok=; b=frXzlH159CBSMH /Tz3Q+uo0iOzP0NQCsuNT1AfR0SjDzRRzxqFxegvOYupE6hHnSC5AtA6Vmz2gNKGHOa3G0MF4ExYj E0deodHZ8n1k1SP/LQI0d9uHnlTNFr4fzJCOyKTtJLuPbKKJJUT1tWsNGRSUBdEr2Mm4NRFmz0dp5 FJ0e9S/REhdAyRVG7wataisIGuSQgUkiXi+bOI0FzEl20e7k5a4Uc8+IDOg6nbHdHPs9uyirvg+Iv OXYSUFxaUBSqRuW3e3P09NjLe9rX1kJrqEuAwaJON1j99hX0sUD7XJW8UHe86diKRv4z6O0D1p/ip fAt0yjrujzFwiUkA6zpQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iUVp3-0000kA-Rv; Tue, 12 Nov 2019 13:03:05 +0000 Received: from smtp2.axis.com ([195.60.68.18]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iUVp0-0000jC-D8 for linux-arm-kernel@lists.infradead.org; Tue, 12 Nov 2019 13:03:04 +0000 IronPort-SDR: +v4yHbmv8wg5r4Nll65SWyYY7rw7sYmaq+540BFCcptQQI+X8o5Lf5m+gL9L5NgI8urgqp4tgV Sm1z579RAtph5YM11zTs7eNyeE+I5fSHT/S3mTRPbJEsYPPkF79hP7y6JBFyDur+Tw7fY80YhU 6HrGb4R+9dQzujnSmNb9uD+nkfmJwK1y4Wc6tRop07GJ7HsdlaCZof43Nn2upDx46iCebYt/Wl zdFMHgIQSkK7o3VdMjdQDuuK8HqGtwY//ON+EXbwGqv1vvEL62pQsT/9Aq3Geu2wOjflIFEc1J RAU= X-IronPort-AV: E=Sophos;i="5.68,296,1569276000"; d="scan'208";a="2339766" X-Axis-User: NO X-Axis-NonUser: YES X-Virus-Scanned: Debian amavisd-new at bes.se.axis.com From: Vincent Whitchurch To: torvalds@linux-foundation.org Subject: [PATCH v2] buffer: Fix I/O error due to ARM read-after-read hazard Date: Tue, 12 Nov 2019 14:02:44 +0100 Message-Id: <20191112130244.16630-1-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.20.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191112_050302_772165_2432695C X-CRM114-Status: GOOD ( 10.98 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: axboe@kernel.dk, Vincent Whitchurch , catalin.marinas@arm.com, linux@armlinux.org.uk, linux-kernel@vger.kernel.org, will@kernel.org, linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org On my dual-core ARM Cortex-A9, reading from squashfs (over dm-verity/ubi/mtd) in a loop for hundreds of hours invariably results in a read failure in squashfs_read_data(). The errors occur because the buffer_uptodate() check fails after wait_on_buffer(). Further debugging shows that the bh was in fact uptodate and that there is no actual I/O error in the lower layers. The problem is caused by the read-after-read hazards in the ARM Cortex-A9 MPCore (erratum #761319, see [1]). The code generated by the compiler for the combination of the wait_on_buffer() and buffer_uptodate() calls reads the flags value twice from memory (see the excerpt of the assembly below). The new value of the BH_Lock flag is seen but the new value of BH_Uptodate is not even though both the bits are read from the same memory location. 27c: 9d08 ldr r5, [sp, #32] 27e: 2400 movs r4, #0 280: e006 b.n 290 282: 6803 ldr r3, [r0, #0] 284: 07da lsls r2, r3, #31 286: f140 810d bpl.w 4a4 28a: 3401 adds r4, #1 28c: 42bc cmp r4, r7 28e: da08 bge.n 2a2 290: f855 0f04 ldr.w r0, [r5, #4]! 294: 6803 ldr r3, [r0, #0] 296: 0759 lsls r1, r3, #29 298: d5f3 bpl.n 282 29a: f7ff fffe bl 0 <__wait_on_buffer> Work around this problem by adding a DMB between the two reads of bh->flags, as recommended in the ARM document. With this barrier, no failures have been seen in more than 5000 hours of the same test. [1] http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a/UAN0004A_a9_read_read.pdf Signed-off-by: Vincent Whitchurch --- v2: Reword commit message. include/linux/buffer_head.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 7b73ef7f902d..4ef909a91f8c 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -352,6 +352,14 @@ static inline void wait_on_buffer(struct buffer_head *bh) might_sleep(); if (buffer_locked(bh)) __wait_on_buffer(bh); + +#ifdef CONFIG_ARM + /* + * Work around ARM Cortex-A9 MPcore Read-after-Read Hazards (erratum + * 761319). + */ + smp_rmb(); +#endif } static inline int trylock_buffer(struct buffer_head *bh) -- 2.20.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel