On Mon, Sep 14, 2026 at 11:37:54AM -0700, Kees Cook wrote:
> On Mon, Sep 14, 2026 at 10:22:19AM +0100, Lorenzo Stoakes (ARM) wrote:
> > Care is taken to ensure that external rust modules can still be built
> > against the tree - make modules_prepare ... (where ... are other goals)
> > will build rust/ first.
> > [...]
> > prepare: prepare0
> > ifdef CONFIG_RUST
> > +$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh
> > - $(Q)$(MAKE) $(build)=rust
> > endif
> >
> > PHONY += remove-stale-files
> > @@ -1760,6 +1763,12 @@ modules: modules_prepare
> > # Target to prepare building external modules
> > modules_prepare: prepare
> > $(Q)$(MAKE) $(build)=scripts scripts/module.lds
> > +ifdef CONFIG_RUST
> > +# Ensure rust/ is built before any external rust module which will rely
> > upon it.
> > +ifneq ($(filter modules_prepare,$(MAKECMDGOALS)),)
> > + $(Q)$(MAKE) $(build)=rust
> > +endif
> > +endif
>
> As far as I can see, nothing orders this recipe against the tree build,
> which also descends into rust/ through "obj-$(CONFIG_RUST) += rust/"
> in Kbuild, while $(build-dir) only depends on prepare. Before this
> patch that was fine, because prepare had already built rust/ by the
> time either of them ran. Now "make -jN modules_prepare all" can have
> two make processes building rust/ at the same time, and so can
> "make -jN rustdoc all" or "make -jN rusttest all", whose recipes also
> run "$(MAKE) $(build)=rust". That means two rustc runs writing the same
> objects in rust/ ...
Ack.
It seems make can't order two independent sub-makes, so will change the patch so
it skips the modules_prepare rust build when a goal that builds the tree* is
present, as they all descend into rust/ themselves.
I checked the change against:
$ make modules_prepare
$ make modules_prepare scripts
$ make -j128 modules_prepare all
+ confirmed they all built rust/ once only for each.
* LLM says: all, vmlinux, modules, image targets, dtbs, rustdoc, rusttest
So, fixed in v3 :)
>
> > +# Rust code elsewhere in the tree depends upon rust/.
> > +ifdef CONFIG_RUST
> > +$(KBUILD_RUST_DIRS): | rust
> > +endif
> > [...]
> > +export KBUILD_RUST_DIRS := drivers lib mm samples
>
> Doesn't this make all of drivers/, lib/, mm/ and samples/ wait for rust/?
> That's a lot of stall: drivers/ is most of the tree. I think then a
> CONFIG_RUST build has most of its C work waiting on the rust chain;
> only the other top-level directories start early? This didn't create new
> build delays for those configurations?
Yeah good point.
For a defconfig+rust clean build on 128 threads the other top-level directories
were done at ~14s while rust ran to ~18.6s, so there was 4-5 of idle.
However the patch improves things by net -3.9s regardless.
This is really only a big box issue though. With fewer threads the rest of the
tree takes longer so it has no impact on the build.
(An aside - this kind of trade-off is what the series is all about really - the
'serial tail' - i.e. the single threaded stuff that _overlaps_ the end of the
build is what slows you down.)
Since this _still_ gives you a significant speed up on bigger boxes, I think
it's fine as-is.
The LLM says a fix for this would need significant work - a cross-instance lock
and an on-demand rust/ build. So I think best as a follow-up?
>
> --
> Kees Cook
--
Cheers, Lorenzo