[PATCH 10/23] kbuild: cache list, composite object state per object
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
Date: 2026-09-08 20:57:25
Also in:
linux-arch, linux-doc, linux-efi, linux-kbuild, linux-riscv, lkml, llvm
Subsystem:
kernel build + files below scripts/ (unless maintained elsewhere), the rest · Maintainers:
Nathan Chancellor, Nicolas Schier, Linus Torvalds
When each object's command line is expanded, kbuild has to figure out on
multiple occasions whether it's built-in or part of a module and which
composite object it belongs to.
This causes the time spent on each directory in the kernel tree to grow
O(n^2) with its object count, which is especially problematic for instance
in drivers/gpu/drm/amd/amdgpu with 310 objects.
No-op builds (i.e. make -j $(nproc) when nothing has changed) are
particularly impacted by this.
Fix the issue by caching this data and looking it up instead of getting it
over and over again.
This has a particularly large impact on allmodconfig builds.
Whole build, 128-thread Threadripper 9980X, best of N runs:
before after delta
-------------------------------
x86 defconfig, no-op make, gcc 0.94s 0.92s -0.02s (-2%)
x86 defconfig, no-op make, clang 1.1s 1.1s -0.01s (-1%)
x86 allmodconfig, no-op make, gcc 13.0s 12.3s -0.64s (-5%)
x86 allmodconfig, no-op make, clang 13.8s 13.2s -0.64s (-5%)
x86 allmodconfig, touch mm/vma.c, gcc 41.6s 40.9s -0.70s (-2%)
x86 allmodconfig, touch mm/vma.c, clang 38.1s 37.6s -0.52s (-1%)
Assisted-by: LLM
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
---
scripts/Makefile.build | 8 ++++++++
scripts/Makefile.lib | 7 +++----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 4349108e75e1..2cabfe85b798 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build@@ -122,6 +122,14 @@ multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) subdir-ym := $(addprefix $(obj)/, $(subdir-ym)) endif +# Cache which list each object is in and which composite objects it belongs to, +# once per object for $(part-of-builtin), $(part-of-module) and $(modname-multi). +$(foreach o, $(real-obj-y) $(lib-y), $(eval part-of-builtin_$o := y)) +$(foreach o, $(real-obj-m), $(eval part-of-module_$o := y)) +$(foreach m, $(multi-obj-ym), \ + $(foreach o, $(call suffix-search, $m, .o, -objs -y -m), \ + $(eval modname-multi_$o += $(m:.o=)))) + ifndef obj $(warning kbuild: Makefile.build is included improperly) endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a4fdd8bd975..2f447bc25e7b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib@@ -2,8 +2,7 @@ # Finds the multi-part object the current object will be linked into. # If the object belongs to two or more multi-part objects, list them all. -modname-multi = $(sort $(foreach m,$(multi-obj-ym),\ - $(if $(filter $*.o, $(call suffix-search, $m, .o, -objs -y -m)),$(m:.o=)))) +modname-multi = $(sort $(modname-multi_$*.o)) __modname = $(or $(modname-multi),$(basetarget))
@@ -149,8 +148,8 @@ endif # If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules is-kernel-object = $(or $(part-of-builtin),$(part-of-module)) -part-of-builtin = $(if $(filter $(basename $@).o, $(real-obj-y) $(lib-y)),y) -part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y) +part-of-builtin = $(part-of-builtin_$(basename $@).o) +part-of-module = $(part-of-module_$(basename $@).o) quiet_modtag = $(if $(part-of-module),[M], ) modkern_cflags = \
--
2.55.0