On Wed, Jan 7, 2026 at 2:40 PM Andreas Hindborg <[email protected]> wrote: > > "Peter Zijlstra" <[email protected]> writes: > > > On Wed, Jan 07, 2026 at 02:12:10PM +0100, Andreas Hindborg wrote: > >> "Peter Zijlstra" <[email protected]> writes: > >> > >> > On Wed, Jan 07, 2026 at 01:23:38PM +0100, Andreas Hindborg wrote: > >> >> Hi Alice, > >> >> > >> >> Alice Ryhl <[email protected]> writes: > >> >> > >> >> > Currently the only way for Rust code to call a static inline function > >> >> > is > >> >> > to go through a helper in rust/helpers/. This introduces performance > >> >> > costs due to additional function calls and also clutters backtraces > >> >> > and > >> >> > flame graphs with helper symbols. > >> >> > > >> >> > To get rid of these helper symbols, provide functionality to inline > >> >> > helpers into Rust using llvm-link. This option complements full LTO, > >> >> > by > >> >> > being much cheaper and avoiding incompatibility with BTF. > >> >> > > >> >> > I ran a microbenchmark showing the benefit of this. All the benchmark > >> >> > does is call refcount_inc() in a loop. This was chosen since > >> >> > refcounting > >> >> > is quite hot in Binder. The results are that Rust spends 6.35 ns per > >> >> > call vs 5.73 ns per call in C. When enabling this option, the two > >> >> > languages become equally fast, and disassembly confirms the exact same > >> >> > machine code is used (in particular there is no call to > >> >> > rust_helper_refcount_inc). Benchmarking Binder also results in an > >> >> > improvement from this change. > >> >> > > >> >> > This patch is complementary to: > >> >> > https://lore.kernel.org/all/[email protected]/ > >> >> > > >> >> > Signed-off-by: Alice Ryhl <[email protected]> > >> >> > >> >> I get the following modpost errors when building with this applied on > >> >> top > >> >> of v6.19-rc4: > >> >> > >> >> ERROR: modpost: "__SCK__WARN_trap" [drivers/gpu/drm/nova/nova.ko] > >> >> undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [drivers/gpu/nova-core/nova_core.ko] > >> >> undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [drivers/block/rnull/rnull_mod.ko] > >> >> undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [samples/rust/rust_minimal.ko] > >> >> undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [samples/rust/rust_misc_device.ko] > >> >> undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [samples/rust/rust_print.ko] > >> >> undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [samples/rust/rust_dma.ko] undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [samples/rust/rust_driver_pci.ko] > >> >> undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" > >> >> [samples/rust/rust_driver_platform.ko] undefined! > >> >> ERROR: modpost: "__SCK__WARN_trap" [samples/rust/rust_driver_faux.ko] > >> >> undefined! > >> > > >> > Looks like it used the wrong static_call_mod() version, was MODULE > >> > defined? > >> > >> CONFIG_MODULES=y, yes > >> > >> I built without the patch first, then applied the series, enabled the > >> option via menuconfig and ran the build. I thought maybe some dependency > >> check is messed up so I retried the build from a clean state. Same > >> result. > > > > No, I mean -DMODULE. Note how the quiet_cmd_bindgen target has -DMODULE, > > but the new quiet_cmd_rust_helper target does not. > > Ah, that did the trick, thanks! > > diff --git a/rust/Makefile b/rust/Makefile > index 5365d53b6cf96..08d3dc1038cf5 100644 > --- a/rust/Makefile > +++ b/rust/Makefile > @@ -483,7 +483,7 @@ $(obj)/bindings/bindings_helpers_generated.rs: > $(src)/helpers/helpers.c FORCE > > quiet_cmd_rust_helper = HELPER $@ > cmd_rust_helper = \ > - $(CC) $(filter-out $(CFLAGS_REMOVE_helpers/helpers.o), $(c_flags)) -c > -g0 $< -emit-llvm -o $@ > + $(CC) $(filter-out $(CFLAGS_REMOVE_helpers/helpers.o), $(c_flags)) > -DMODULE -c -g0 $< -emit-llvm -o $@ > > $(obj)/helpers/helpers.bc: $(obj)/helpers/helpers.c FORCE > +$(call if_changed_dep,rust_helper) > > Is -DMOUDLE always appropriate to pass to the helpers? The helpers are > also inlined into non module code.
With this option, helpers.bc gets linked into every Rust object file separately (and symbols are internalized). We might want a separate .bc file depending on whether the Rust object files is part of the core kernel or a .ko file. Alice
