[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251202-inline-helpers-v1-2-879dae33a66a@google.com>
Date: Tue, 02 Dec 2025 20:27:57 +0000
From: Alice Ryhl <aliceryhl@...gle.com>
To: Miguel Ojeda <ojeda@...nel.org>
Cc: Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
"Björn Roy Baron" <bjorn3_gh@...tonmail.com>, Benno Lossin <lossin@...nel.org>,
Andreas Hindborg <a.hindborg@...nel.org>, Trevor Gross <tmgross@...ch.edu>,
Danilo Krummrich <dakr@...nel.org>, Alexandre Courbot <acourbot@...dia.com>, Will Deacon <will@...nel.org>,
Peter Zijlstra <peterz@...radead.org>, Mark Rutland <mark.rutland@....com>,
Nathan Chancellor <nathan@...nel.org>, Nick Desaulniers <nick.desaulniers+lkml@...il.com>,
Bill Wendling <morbo@...gle.com>, Justin Stitt <justinstitt@...gle.com>,
Nicolas Schier <nicolas.schier@...ux.dev>, Andrew Morton <akpm@...ux-foundation.org>,
Uladzislau Rezki <urezki@...il.com>, rust-for-linux@...r.kernel.org,
linux-kernel@...r.kernel.org, llvm@...ts.linux.dev,
linux-kbuild@...r.kernel.org, linux-mm@...ck.org,
nouveau@...ts.freedesktop.org, Alice Ryhl <aliceryhl@...gle.com>
Subject: [PATCH 2/4] rust: helpers: #define __rust_helper
From: Gary Guo <gary@...yguo.net>
Because of LLVM inling checks, it's generally not possible to inline a C
helper into Rust code, even with LTO:
* LLVM doesn't want to inline functions compiled with
`-fno-delete-null-pointer-checks` with code compiled without. The C
CGUs all have this enabled and Rust CGUs don't. Inlining is okay since
this is one of the hardening features that does not change the ABI,
and we shouldn't have null pointer dereferences in these helpers.
* LLVM doesn't want to inline functions with different list of builtins. C
side has `-fno-builtin-wcslen`; `wcslen` is not a Rust builtin, so
they should be compatible, but LLVM does not perform inlining due to
attributes mismatch.
* clang and Rust doesn't have the exact target string. Clang generates
`+cmov,+cx8,+fxsr` but Rust doesn't enable them (in fact, Rust will
complain if `-Ctarget-feature=+cmov,+cx8,+fxsr` is used). x86-64
always enable these features, so they are in fact the same target
string, but LLVM doesn't understand this and so inlining is inhibited.
This can be bypassed with `--ignore-tti-inline-compatible`, but this
is a hidden option.
To fix this, we can add __always_inline on every helper, which skips
these LLVM inlining checks. For this purpose, introduce a new
__rust_helper macro that needs to be added to every helper.
The actual additions of __rust_helper can happen in separate patches. A
"flag day" change is not required since missing annotations do not lead
to anything worse than missing inlining.
Signed-off-by: Gary Guo <gary@...yguo.net>
Signed-off-by: Alice Ryhl <aliceryhl@...gle.com>
---
rust/helpers/atomic.c | 5 -----
rust/helpers/helpers.c | 31 +++++++++++++++++++++++++++++++
scripts/atomic/gen-rust-atomic-helpers.sh | 5 -----
3 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/rust/helpers/atomic.c b/rust/helpers/atomic.c
index cf06b7ef9a1c559e8d7bdfc2bcd2aeb8951c29d1..a48605628ed73ac32aae2e6280481407a670e88f 100644
--- a/rust/helpers/atomic.c
+++ b/rust/helpers/atomic.c
@@ -11,11 +11,6 @@
#include <linux/atomic.h>
-// TODO: Remove this after INLINE_HELPERS support is added.
-#ifndef __rust_helper
-#define __rust_helper
-#endif
-
__rust_helper int
rust_helper_atomic_read(const atomic_t *v)
{
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 551da6c9b5064c324d6f62bafcec672c6c6f5bee..d0e2f1f9b449b2248cfbddcee1e8bf9becc8a2f9 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -7,6 +7,37 @@
* Sorted alphabetically.
*/
+#include <linux/compiler_types.h>
+
+#ifdef __BINDGEN__
+// Omit `inline` for bindgen as it ignores inline functions.
+#define __rust_helper
+#else
+// The helper functions are all inline functions.
+//
+// We use `__always_inline` here to bypass LLVM inlining checks, in case the
+// helpers are inlined directly into Rust CGUs.
+//
+// The LLVM inlining checks are false positives:
+// * LLVM doesn't want to inline functions compiled with
+// `-fno-delete-null-pointer-checks` with code compiled without.
+// The C CGUs all have this enabled and Rust CGUs don't. Inlining is okay
+// since this is one of the hardening features that does not change the ABI,
+// and we shouldn't have null pointer dereferences in these helpers.
+// * LLVM doesn't want to inline functions with different list of builtins. C
+// side has `-fno-builtin-wcslen`; `wcslen` is not a Rust builtin, so they
+// should be compatible, but LLVM does not perform inlining due to attributes
+// mismatch.
+// * clang and Rust doesn't have the exact target string. Clang generates
+// `+cmov,+cx8,+fxsr` but Rust doesn't enable them (in fact, Rust will
+// complain if `-Ctarget-feature=+cmov,+cx8,+fxsr` is used). x86-64 always
+// enable these features, so they are in fact the same target string, but
+// LLVM doesn't understand this and so inlining is inhibited. This can be
+// bypassed with `--ignore-tti-inline-compatible`, but this is a hidden
+// option.
+#define __rust_helper __always_inline
+#endif
+
#include "atomic.c"
#include "auxiliary.c"
#include "barrier.c"
diff --git a/scripts/atomic/gen-rust-atomic-helpers.sh b/scripts/atomic/gen-rust-atomic-helpers.sh
index 45b1e100ed7c63108ee6cb07e48a17668f860d47..a3732153af29f415e397e17cab6e75cb5d7efafc 100755
--- a/scripts/atomic/gen-rust-atomic-helpers.sh
+++ b/scripts/atomic/gen-rust-atomic-helpers.sh
@@ -47,11 +47,6 @@ cat << EOF
#include <linux/atomic.h>
-// TODO: Remove this after INLINE_HELPERS support is added.
-#ifndef __rust_helper
-#define __rust_helper
-#endif
-
EOF
grep '^[a-z]' "$1" | while read name meta args; do
--
2.52.0.158.g65b55ccf14-goog
Powered by blists - more mailing lists