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

Reply via email to