From patchwork Wed Oct 2 01:02:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Desnoyers X-Patchwork-Id: 13819081 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1EF4CF3189 for ; Wed, 2 Oct 2024 01:04:45 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C6A73680047; Tue, 1 Oct 2024 21:04:43 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C1D76680045; Tue, 1 Oct 2024 21:04:43 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9C956680047; Tue, 1 Oct 2024 21:04:43 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 74ADB68002B for ; Tue, 1 Oct 2024 21:04:43 -0400 (EDT) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id E6F4C14159C for ; Wed, 2 Oct 2024 01:04:42 +0000 (UTC) X-FDA: 82626867204.27.033F831 Received: from smtpout.efficios.com (smtpout.efficios.com [167.114.26.122]) by imf11.hostedemail.com (Postfix) with ESMTP id 58E2140005 for ; Wed, 2 Oct 2024 01:04:41 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=pass header.d=efficios.com header.s=smtpout1 header.b=kThGxzqm; spf=pass (imf11.hostedemail.com: domain of mathieu.desnoyers@efficios.com designates 167.114.26.122 as permitted sender) smtp.mailfrom=mathieu.desnoyers@efficios.com; dmarc=pass (policy=none) header.from=efficios.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1727830953; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=8KrjyG7UJVLDweqHlvxnqxw3ltq+4n3/lbHvzWngHaI=; b=kCnUyAI8qiNH0nBG0cO1d9Cf6h7lmk24PZHa/DFO+IBUtbJo7N99E7VfM+8w0CeuuRfV2N AxbM3ux4A6/3JukfoMuORFUjuKLVjQLz2Kd/v2kmIWMCyWBqGBy7cshiEyTzzQ+h9AuHVO 365xIGdfwAYmbGkLHb5Zj2DVyt2xXEg= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1727830953; a=rsa-sha256; cv=none; b=WXVYAEno9gHgnbYvnGCQC5ezwmNcXLDwnvMQ78gx6OetVfGUaUiDerlNffGBttrux0R6Mr 4af9HS74nvwTzmWy9bQFleYEvy/V8Jz/u/UDQM4EAx5BEnPObAKuRTxdPYksiuGSw3/BZz QlG6hy1hpUaN8q9vq8kMwnxF+4FyxTE= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=pass header.d=efficios.com header.s=smtpout1 header.b=kThGxzqm; spf=pass (imf11.hostedemail.com: domain of mathieu.desnoyers@efficios.com designates 167.114.26.122 as permitted sender) smtp.mailfrom=mathieu.desnoyers@efficios.com; dmarc=pass (policy=none) header.from=efficios.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=efficios.com; s=smtpout1; t=1727831080; bh=eumWImPFsrX/ZuZnIIsDwO32qp7NYwQGZnsiXAMqNR4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kThGxzqmna0mbJ4PbssiWmX/BbPYXO8M5axEv9WOQMzumAQ53j1/oVSMNu8gKySqp f+TKwzph7C9tRlgVpbFQ6lCs9Ff9rZARWu8/iQPDOAVjYuK0zZ+1GiS7rFrQtGe9R2 /t3iyg4We7QxR8Fg56xcGBNAl/Ueuuu7bRaPTUf92dq2RF9drLyD2fw4QSD1uM1TSF sd3nShCSpSLLNu5F6KUlIPwxhB9tW/1sT1SlXOUK40eRgr/jhs0jQq6+ky1RlaLnW7 sQ1sAvKd64Dhjpdnt8bg3LsKMM59l4xzoSg50SNIjgVljv5h7VUY9GOJRzweBq+8lD E+8mHfbUTVkWA== Received: from thinkos.internal.efficios.com (unknown [IPv6:2606:6d00:100:4000:cacb:9855:de1f:ded2]) by smtpout.efficios.com (Postfix) with ESMTPSA id 4XJGml5tn7zj4J; Tue, 1 Oct 2024 21:04:39 -0400 (EDT) From: Mathieu Desnoyers To: Linus Torvalds , Andrew Morton , Peter Zijlstra Cc: linux-kernel@vger.kernel.org, Mathieu Desnoyers , Nicholas Piggin , Michael Ellerman , Greg Kroah-Hartman , Sebastian Andrzej Siewior , "Paul E. McKenney" , Will Deacon , Boqun Feng , Alan Stern , John Stultz , Neeraj Upadhyay , Frederic Weisbecker , Joel Fernandes , Josh Triplett , Uladzislau Rezki , Steven Rostedt , Lai Jiangshan , Zqiang , Ingo Molnar , Waiman Long , Mark Rutland , Thomas Gleixner , Vlastimil Babka , maged.michael@gmail.com, Mateusz Guzik , Jonas Oberhauser , rcu@vger.kernel.org, linux-mm@kvack.org, lkmm@lists.linux.dev, Gary Guo , Nikita Popov , llvm@lists.linux.dev Subject: [RFC PATCH 1/4] compiler.h: Introduce ptr_eq() to preserve address dependency Date: Tue, 1 Oct 2024 21:02:02 -0400 Message-Id: <20241002010205.1341915-2-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20241002010205.1341915-1-mathieu.desnoyers@efficios.com> References: <20241002010205.1341915-1-mathieu.desnoyers@efficios.com> MIME-Version: 1.0 X-Stat-Signature: mhraw3o3g8npmsiz5caoaxypwww3tc68 X-Rspamd-Queue-Id: 58E2140005 X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1727831081-78177 X-HE-Meta: U2FsdGVkX1/lW/pmUwecUHpj7RhH7maI3i/N3dksB8rQPIVG32VUDvtpj1eQZwV+bUvTnv51HvSDFvqd1FseAv5l6H+TpxnYtm8RZtCc64jqv446rZF9w3lZM0HwxrrrTnv8jaH+4hhU/65XhDt7euxWHSY3p5uClvA2ZYkdXpEnEkMhAcBcH6E6eiFsmM4cKayR6CAk13UjEJweAeSXJDUxxIX4pt4y3fuy6E/PndMwv/23P8XvEb73/u15FSqA3Mz2S8B4EdIxGZo9xGDHlS400dgZtzZ2m2e2j64qbpKKFVWodeS1MCGKn3p16LL8iYJNTveqVYiHN/4EeLzq6p/jfQDPJb4egLnAIDy3iuf1HWL4NwWWQQ+F6/jmRvL+WDxp2RoYuIYnkRpXrxxIBnBU80KusdyZuCUE5uvRxWGKWhxpXuCsc5yWFvw7aCvEaDfTPELsIXj5yBPsNtIItYRgxRidF9yzk6AeRGRTTAOdcvQpBgEo8p6hlkOu/RVeluaL6A03ixemmu/H9SYX44Zitt0RSaJNUx8bV46o7QFmV0D/cH21pknib/U3I7rIIL8BeRJbkB6ss7gGy++UrUm73tdPyTSI3JX1crt5bk1LBNEef7RcQ8Nv3CkKxfLKoDEgDXQOztbdTg6xjmme5A1sIkCDjAXwYS+KKq+iAZ5IZYRwDR6OXc2Jnyz3xmzz4lTaPrs6J7y96Y42YvqsZA8IdAuFL1zGtQmfhzC/ER4OTBp6X9/FGvyuwqF/sNX0q21yeNqT/0ZEZIFe0wt9vNk+VSPj4C3XTBwTlZMs7iWdrTIUaiGtl6J7zM+IHdIHsYAHZPufxy7N5vqbfXULKL94B3Kfhi9Xkg8tOkRwP4NioJj1rKrithKz4vawz1c0fOhe6dOctqi/SZmL5R/R91bLQx7FFeCyN0+K83fKAAK/niqRkzOTmuDJIk+df4pZw59PeoiY8qUgaqEQUwm ye4WO+l2 MQu78gw54TH4qF2Hyv9iC9HVinwJb98rRIte3zsWGmASXv7+lp+Lkw5IWdtdguRZFgV7u+FWA++TUmCjAElJFrPLQWF6wy4UfpE9UdnEg5WUzGUmGIzJi4ZGfZTy+VhZBR1ndyA9j1+86ZmvEDgQ1v0X8KlMruPtk4bbyNOeRzsfFHV5QjLHQrmHzZ2paffcStasWngG8dlvDDNVj/eZNTQE1KxCgDPZalrX+K8uNruyO/wHTvgPrmBHOaMcQvUadE+cW1TG0MVTa0F0DDz8VxPfvxIyOqHcQ5M+y+RKzL9ZjBLymVghcYctqG53Fw1LSaiA6YR+FyZEMFooEj40p727H+ei+jKSX8srjZa/PN2hF3/mpEYz16dLhHTuKc4SRmX5+BA7n0MVwFuH0zXf5/iqmFZky0bOF3NOHnSvX59C4Uqg8rGenqKZb97oo0wVtAxAS08tupH08JMEBTqKdg9ACFUNke0MKe1m00MpkbclA2iQwXYSCpyk0DdxrW201Pv9OwR9BQODx2Y9FY3ejwX+MYTfTotEhCLrFttGJGTmjls+waIxg01s1lIaSXqUaShJxYycYRqt60SWYKZ/BlS9DhJvPuDxn0s+Zv/qbxwCOjvrpltk1e8eQaFvJRdUEjrUXUO2SDBOm2OWMLiJUSwPIGcut5KkvlD4Wdwi5K0s4Vh4QMFO7VOkKxsAXt5yEjaAXHS1NOZJYuUuJU0oETPhvnbke+EYlw5yhrYs+snTHTVn324tUlDF84m/3rnPBRh84zRw0QfVsttZVwvK/TKb8tjFK4SIFrRPiwVAQ6BpJsx1cq7L1QRkgCROY+5c2c6Swh+6COAMWGeDEjXAozObjeNm8ZvagK9rJv6zqItsM06td4S1XKBzJkesrq85eEL64zQh2I95iIg+CrhUa3879HxEL25iVZM9KnTzW+z4sWqjTRkEeOklgZ1JhNyd2rmy6AP6jlpIuXxoOKRExwjQe+005 SRn3KwA9 74onh56DGPTvMjuv+HkeVNmWbAdbrtXdtedmWFh7erJMM5L87wVYjXROCzRMrEEss0d40X8j3SWoeoIqOO+YRhWOTfAIg+DcxhSXCzs871++Hz9krkOXwRobJBDyWEoPQS22ADRjRnLRbjmIBqgvPnN4kn/jejW3KZc6feWCGPz7YeE9A4ABcE0nTUUj+JkXmNdAlcB6+jo= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Compiler CSE and SSA GVN optimizations can cause the address dependency of addresses returned by rcu_dereference to be lost when comparing those pointers with either constants or previously loaded pointers. Introduce ptr_eq() to compare two addresses while preserving the address dependencies for later use of the address. It should be used when comparing an address returned by rcu_dereference(). This is needed to prevent the compiler CSE and SSA GVN optimizations from using @a (or @b) in places where the source refers to @b (or @a) based on the fact that after the comparison, the two are known to be equal, which does not preserve address dependencies and allows the following misordering speculations: - If @b is a constant, the compiler can issue the loads which depend on @a before loading @a. - If @b is a register populated by a prior load, weakly-ordered CPUs can speculate loads which depend on @a before loading @a. The same logic applies with @a and @b swapped. Suggested-by: Linus Torvalds Suggested-by: Boqun Feng Signed-off-by: Mathieu Desnoyers Reviewed-by: Boqun Feng Acked-by: "Paul E. McKenney" Acked-by: Alan Stern Cc: Greg Kroah-Hartman Cc: Sebastian Andrzej Siewior Cc: "Paul E. McKenney" Cc: Will Deacon Cc: Peter Zijlstra Cc: Boqun Feng Cc: Alan Stern Cc: John Stultz Cc: Neeraj Upadhyay Cc: Linus Torvalds Cc: Boqun Feng Cc: Frederic Weisbecker Cc: Joel Fernandes Cc: Josh Triplett Cc: Uladzislau Rezki Cc: Steven Rostedt Cc: Lai Jiangshan Cc: Zqiang Cc: Ingo Molnar Cc: Waiman Long Cc: Mark Rutland Cc: Thomas Gleixner Cc: Vlastimil Babka Cc: maged.michael@gmail.com Cc: Mateusz Guzik Cc: Gary Guo Cc: Jonas Oberhauser Cc: rcu@vger.kernel.org Cc: linux-mm@kvack.org Cc: lkmm@lists.linux.dev Cc: Nikita Popov Cc: llvm@lists.linux.dev Reviewed-by: Joel Fernandes (Google) Tested-by: Joel Fernandes (Google) --- Changes since v0: - Include feedback from Alan Stern. --- include/linux/compiler.h | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 2df665fa2964..75a378ae7af1 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -186,6 +186,69 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, __asm__ ("" : "=r" (var) : "0" (var)) #endif +/* + * Compare two addresses while preserving the address dependencies for + * later use of the address. It should be used when comparing an address + * returned by rcu_dereference(). + * + * This is needed to prevent the compiler CSE and SSA GVN optimizations + * from using @a (or @b) in places where the source refers to @b (or @a) + * based on the fact that after the comparison, the two are known to be + * equal, which does not preserve address dependencies and allows the + * following misordering speculations: + * + * - If @b is a constant, the compiler can issue the loads which depend + * on @a before loading @a. + * - If @b is a register populated by a prior load, weakly-ordered + * CPUs can speculate loads which depend on @a before loading @a. + * + * The same logic applies with @a and @b swapped. + * + * Return value: true if pointers are equal, false otherwise. + * + * The compiler barrier() is ineffective at fixing this issue. It does + * not prevent the compiler CSE from losing the address dependency: + * + * int fct_2_volatile_barriers(void) + * { + * int *a, *b; + * + * do { + * a = READ_ONCE(p); + * asm volatile ("" : : : "memory"); + * b = READ_ONCE(p); + * } while (a != b); + * asm volatile ("" : : : "memory"); <-- barrier() + * return *b; + * } + * + * With gcc 14.2 (arm64): + * + * fct_2_volatile_barriers: + * adrp x0, .LANCHOR0 + * add x0, x0, :lo12:.LANCHOR0 + * .L2: + * ldr x1, [x0] <-- x1 populated by first load. + * ldr x2, [x0] + * cmp x1, x2 + * bne .L2 + * ldr w0, [x1] <-- x1 is used for access which should depend on b. + * ret + * + * On weakly-ordered architectures, this lets CPU speculation use the + * result from the first load to speculate "ldr w0, [x1]" before + * "ldr x2, [x0]". + * Based on the RCU documentation, the control dependency does not + * prevent the CPU from speculating loads. + */ +static __always_inline +int ptr_eq(const volatile void *a, const volatile void *b) +{ + OPTIMIZER_HIDE_VAR(a); + OPTIMIZER_HIDE_VAR(b); + return a == b; +} + #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) /**