All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] perf tests: Improvements to build-test performance
@ 2026-09-02 15:31 Ian Rogers
  2026-09-02 15:40 ` sashiko-bot
  2026-09-03  4:56 ` [PATCH v2] " Ian Rogers
  0 siblings, 2 replies; 7+ messages in thread
From: Ian Rogers @ 2026-09-02 15:31 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark,
	Leo Yan, Michael Jeanson, linux-perf-users, linux-kernel

Replace hardcoded 'make' calls with '$(MAKE)' within tests/make
to ensure GNU Make jobserver file descriptors are properly inherited
by nested builds.

Additionally, remove the notorious 'unexport MAKEFLAGS' from
tools/perf/Makefile. This hack was originally added to prevent
the wrapper's internal '-j$(JOBS)' override from crashing when parent jobserver
tokens were present. Instead, use proper GNU Make conditionals to check
for '-j' or 'jobserver' strings within MAKEFLAGS. If a jobserver is
already orchestrating the build, gracefully back off and let GNU Make
manage parallelism natively.

Finally, optimize the 'out' target (which processes 'run_O' out-of-tree builds)
by stripping sequential bottlenecks like $(call clean) from isolated tmp directories,
and wrapping the target list in a parallel sub-make call.

These combined changes enable 'build-test' out-of-tree targets to
build completely concurrently without severing jobserver tokens.

Unscientifically measured the change lowered the build-test from
around 15 minutes to 10 minutes on a 28 threaded Alderlake CPU. Fixing
the jobserver issues meant the machine remained somewhat usable while
running the test.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
---
 tools/perf/Makefile   | 28 +++++++++++++++++-----------
 tools/perf/tests/make | 14 +++++++-------
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 5b713837eede..45f641e24fb4 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -14,23 +14,29 @@
 .SUFFIXES:
 
 #
-# We don't want to pass along options like -j:
+# If no parallel build was requested, do a parallel build with multiple jobs,
+# based on the number of CPUs online in this system: 'make -j8' on an 8-CPU
+# system, etc.
 #
-unexport MAKEFLAGS
-
-#
-# Do a parallel build with multiple jobs, based on the number of CPUs online
-# in this system: 'make -j8' on a 8-CPU system, etc.
+# If MAKEFLAGS contains '-j' or 'jobserver', JOBS is intentionally left
+# uninitialized so the native GNU Make jobserver can seamlessly control the
+# parallel bounds of the build.
 #
 # (To override it, run 'make JOBS=1' and similar.)
 #
-ifeq ($(JOBS),)
-  JOBS := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
-  ifeq ($(JOBS),0)
-    JOBS := 1
+ifeq ($(findstring -j,$(MAKEFLAGS)),)
+  ifeq ($(findstring jobserver,$(MAKEFLAGS)),)
+    ifeq ($(JOBS),)
+      JOBS := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
+      ifeq ($(JOBS),0)
+        JOBS := 1
+      endif
+    endif
+    PARALLEL_OPT := -j$(JOBS)
   endif
 endif
 
+
 #
 # Only pass canonical directory names as the output directory:
 #
@@ -62,7 +68,7 @@ define print_msg
 endef
 
 define make
-  @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $(SET_DEBUG) $@
+  @$(MAKE) -f Makefile.perf --no-print-directory $(PARALLEL_OPT) O=$(FULL_O) $(SET_DEBUG) $@
 endef
 
 #
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index d2c2f526e1db..4f14c6b72416 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -339,7 +339,6 @@ make_static:
 	rm -rf $@ $$TMP_DEST || (cat $@ ; false)
 
 $(run_O):
-	$(call clean)
 	@TMP_O=$$(mktemp -d); \
 	TMP_DEST=$$(mktemp -d); \
 	cmd="cd $(PERF) && $(MAKE_F) $($(patsubst %_O,%,$@)) $(PARALLEL_OPT) O=$$TMP_O DESTDIR=$$TMP_DEST"; \
@@ -363,18 +362,18 @@ endif
 make_kernelsrc:
 	@echo "- make -C <kernelsrc> $(PARALLEL_OPT) $(K_O_OPT) tools/perf"
 	$(call clean); \
-	(make -C ../.. $(PARALLEL_OPT) $(K_O_OPT) tools/perf) > $@ 2>&1 && \
+	($(MAKE) -C ../.. $(PARALLEL_OPT) $(K_O_OPT) tools/perf) > $@ 2>&1 && \
 	test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false)
 
 make_kernelsrc_tools:
 	@echo "- make -C <kernelsrc>/tools $(PARALLEL_OPT) $(K_O_OPT) perf"
 	$(call clean); \
-	(make -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \
+	($(MAKE) -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \
 	test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false)
 
 make_libperf:
 	@echo "- make -C lib";
-	make -C lib clean >$@ 2>&1; make -C lib >>$@ 2>&1 && rm $@
+	$(MAKE) -C lib clean >$@ 2>&1; $(MAKE) -C lib >>$@ 2>&1 && rm $@
 
 FEATURES_DUMP_FILE := $(FULL_O)/BUILD_TEST_FEATURE_DUMP
 FEATURES_DUMP_FILE_STATIC := $(FULL_O)/BUILD_TEST_FEATURE_DUMP_STATIC
@@ -383,20 +382,21 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools
 	@echo OK
 	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
 
-out: $(run_O)
+out: $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
+	@$(MAKE) -f tests/make $(run_O) PARALLEL_OPT= -j$(cores)
 	@echo OK
 	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
 
 ifeq ($(REUSE_FEATURES_DUMP),1)
 $(FEATURES_DUMP_FILE):
 	$(call clean)
-	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
+	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
 	echo "- $@: $$cmd" && echo $$cmd && \
 	( eval $$cmd ) > /dev/null 2>&1
 
 $(FEATURES_DUMP_FILE_STATIC):
 	$(call clean)
-	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
+	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
 	echo "- $@: $$cmd" && echo $$cmd && \
 	( eval $$cmd ) > /dev/null 2>&1
 
-- 
2.55.0.966.g6673acef38-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v1] perf tests: Improvements to build-test performance
  2026-09-02 15:31 [PATCH v1] perf tests: Improvements to build-test performance Ian Rogers
@ 2026-09-02 15:40 ` sashiko-bot
  2026-09-03  4:56 ` [PATCH v2] " Ian Rogers
  1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-09-02 15:40 UTC (permalink / raw)
  To: Ian Rogers; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The `out` target explicitly passes `-j$(cores)` to a sub-make, breaking GNU Make's native jobserver inheritance and triggering an unbounded fork bomb if `cores` is undefined.
- [Medium] Removing `$(call clean)` from `$(run_O)` causes out-of-tree builds to execute on a dirty source tree when run sequentially after in-tree builds.
--

commit 169a507e0cde997201a5b5a2dfdbe4652f1a9fa0
Author: Ian Rogers <irogers@google.com>

perf tests: Improvements to build-test performance

This commit aims to improve build-test performance by using $(MAKE) to ensure
GNU Make jobserver file descriptors are inherited by nested builds. It removes
sequential bottlenecks like $(call clean) from isolated tmp directories and
wraps the out target list in a parallel sub-make call.

> diff --git a/tools/perf/tests/make b/tools/perf/tests/make
> index d2c2f526e1db0..4f14c6b72416a 100644
> --- a/tools/perf/tests/make
> +++ b/tools/perf/tests/make
> @@ -339,7 +339,6 @@ make_static:
>  	rm -rf $@ $$TMP_DEST || (cat $@ ; false)
>  
>  $(run_O):
> -	$(call clean)

[Severity: Medium]
Does removing this clean step cause out-of-tree builds to execute on a dirty
source tree when run sequentially?

When the default all target is executed:

all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools

The $(run) in-tree builds execute first and leave the source tree dirty.
Since $(run_O) no longer calls $(call clean) before starting, it appears
the first out-of-tree build begins on that dirty source tree, breaking
build isolation.

>  	@TMP_O=$$(mktemp -d); \
>  	TMP_DEST=$$(mktemp -d); \
>  	cmd="cd $(PERF) && $(MAKE_F) $($(patsubst %_O,%,$@)) $(PARALLEL_OPT) O=$$TMP_O DESTDIR=$$TMP_DEST"; \

[ ... ]

> @@ -383,20 +382,21 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools
>  	@echo OK
>  	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
>  
> -out: $(run_O)
> +out: $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
> +	@$(MAKE) -f tests/make $(run_O) PARALLEL_OPT= -j$(cores)

[Severity: High]
Does passing -j$(cores) here break native jobserver inheritance and risk an
unbounded fork bomb?

If a developer runs the out target directly without setting cores, the
-j$(cores) flag expands to -j without an integer. This instructs GNU Make
to spawn unlimited jobs, which is then inherited by all $(run_O) sub-makes.

Additionally, even when cores is defined, passing it explicitly to $(MAKE)
overrides any --jobserver-auth tokens passed from a parent make, breaking
the jobserver inheritance this patch aims to fix.

>  	@echo OK
>  	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260902153135.2067365-1-irogers@google.com?part=1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2] perf tests: Improvements to build-test performance
  2026-09-02 15:31 [PATCH v1] perf tests: Improvements to build-test performance Ian Rogers
  2026-09-02 15:40 ` sashiko-bot
@ 2026-09-03  4:56 ` Ian Rogers
  2026-09-03  5:04   ` sashiko-bot
  2026-09-09 16:10   ` [PATCH v3] " Ian Rogers
  1 sibling, 2 replies; 7+ messages in thread
From: Ian Rogers @ 2026-09-03  4:56 UTC (permalink / raw)
  To: irogers, acme, namhyung
  Cc: adrian.hunter, james.clark, jolsa, leo.yan, linux-kernel,
	linux-perf-users, mingo, mjeanson, peterz

Replace hardcoded 'make' calls with '$(MAKE)' within tests/make to
ensure GNU Make jobserver file descriptors are properly inherited by
nested builds.

Additionally, remove the 'unexport MAKEFLAGS' from
tools/perf/Makefile. This hack was originally added to prevent the
wrapper's internal '-j$(JOBS)' override from crashing when parent
jobserver tokens were present. Instead, use proper GNU Make
conditionals to check for '-j' or 'jobserver' strings within
MAKEFLAGS. If a jobserver is already orchestrating the build,
gracefully back off and let GNU Make manage parallelism natively.

Finally, optimize the 'out' target (which processes 'run_O'
out-of-tree builds) by stripping sequential bottlenecks like $(call
clean) from isolated tmp directories, and wrapping the target list in
a parallel sub-make call.

These combined changes enable 'build-test' out-of-tree targets to
build completely concurrently without severing jobserver tokens.

Unscientifically measured the change lowered the build-test from
around 15 minutes to 10 minutes on a 28 threaded Alderlake CPU. Fixing
the jobserver issues meant the machine remained somewhat usable while
running the test.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
---
v2:
 - Re-structured build-test array in tools/perf/Makefile into explicit
   sequential $(MAKE) passes. This prevents in-tree targets (make_static,
   etc.) from racing to directory corruption when exposed to native
   jobservers.
 - Added '+' prefix to recipe modifiers in tests/make to prevent jobserver
   FDs from being stripped before sub-shell evaluation.
 - Replaced hardcoded -j$(cores) limits in the 'out' sub-make step with
   dynamic jobserver boundary detection to prevent fork-bomb override
   collisions.
 - Restored missing $(call clean) steps via O_CLEAN conditionals to prevent
   in-tree polluted runs from breaking out-of-tree sequences.
 - Removed unconditionally appended $(FEATURES_DUMP_FILE) target restrictions
   from 'out' that threw "No rule to make target" errors on unhandled tests.
 - Fixed 'test_dest_files' to check [ ! -f ] instead of [ ! -x ], removing
   long-standing ghost warnings for non-executable mode-644 targets
   like etc/bash_completion.d/perf.
 - Fixed cosmetic string formatting bugs in GNU Make's print_msg banner
   output.
---
 tools/perf/Makefile   | 35 ++++++++++++++++++++++-------------
 tools/perf/tests/make | 42 ++++++++++++++++++++++++------------------
 2 files changed, 46 insertions(+), 31 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 5b713837eede..2cbf4cb5f093 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -14,23 +14,29 @@
 .SUFFIXES:
 
 #
-# We don't want to pass along options like -j:
+# If no parallel build was requested, do a parallel build with multiple jobs,
+# based on the number of CPUs online in this system: 'make -j8' on an 8-CPU
+# system, etc.
 #
-unexport MAKEFLAGS
-
-#
-# Do a parallel build with multiple jobs, based on the number of CPUs online
-# in this system: 'make -j8' on a 8-CPU system, etc.
+# If MAKEFLAGS contains '-j' or 'jobserver', JOBS is intentionally left
+# uninitialized so the native GNU Make jobserver can seamlessly control the
+# parallel bounds of the build.
 #
 # (To override it, run 'make JOBS=1' and similar.)
 #
-ifeq ($(JOBS),)
-  JOBS := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
-  ifeq ($(JOBS),0)
-    JOBS := 1
+ifeq ($(findstring -j,$(MAKEFLAGS)),)
+  ifeq ($(findstring jobserver,$(MAKEFLAGS)),)
+    ifeq ($(JOBS),)
+      JOBS := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
+      ifeq ($(JOBS),0)
+        JOBS := 1
+      endif
+    endif
+    PARALLEL_OPT := -j$(JOBS)
   endif
 endif
 
+
 #
 # Only pass canonical directory names as the output directory:
 #
@@ -58,11 +64,11 @@ else
 endif
 
 define print_msg
-  @printf '  BUILD:   Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' $(BUILD_TYPE) build\n'
+  @printf '  BUILD:   Doing '\''make\033[33m%s\033[m'\'' $(BUILD_TYPE) build\n' "$(if $(JOBS), -j$(JOBS),)"
 endef
 
 define make
-  @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $(SET_DEBUG) $@
+  @$(MAKE) -f Makefile.perf --no-print-directory $(PARALLEL_OPT) O=$(FULL_O) $(SET_DEBUG) $@
 endef
 
 #
@@ -106,7 +112,10 @@ clean:
 # make -C tools/perf -f tests/make
 #
 build-test:
-	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory tarpkg make_static make_with_gtk2 out
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory tarpkg
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory make_static
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory make_with_gtk2
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory out
 
 build-test-tarball:
 	@$(MAKE) -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory out
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index d2c2f526e1db..d1d99f5a85ae 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -28,15 +28,17 @@ endif
 
 PARALLEL_OPT=
 ifeq ($(SET_PARALLEL),1)
-  ifeq ($(JOBS),)
-    cores := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
-    ifeq ($(cores),0)
-      cores := 1
+  ifeq ($(findstring jobserver,$(MAKEFLAGS))$(findstring -j,$(MAKEFLAGS)),)
+    ifeq ($(JOBS),)
+      cores := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
+      ifeq ($(cores),0)
+        cores := 1
+      endif
+    else
+      cores=$(JOBS)
     endif
-  else
-    cores=$(JOBS)
+    PARALLEL_OPT="-j$(cores)"
   endif
-  PARALLEL_OPT="-j$(cores)"
 endif
 
 # As per kernel Makefile, avoid funny character set dependencies
@@ -230,7 +232,7 @@ test_make_util_pmu_bison_o := test -f $(PERF_O)/util/pmu-bison.o
 
 define test_dest_files
   for file in $(1); do				\
-    if [ ! -x $$TMP_DEST/$$file ]; then		\
+    if [ ! -f $$TMP_DEST/$$file ]; then		\
       echo "  failed to find: $$file";		\
     fi						\
   done
@@ -310,7 +312,7 @@ clean := @(cd $(PERF); $(MAKE_F) -s $(O_OPT) clean >/dev/null && $(MAKE) -s $(O_
 
 $(run):
 	$(call clean)
-	@TMP_DEST=$$(mktemp -d); \
+	+@TMP_DEST=$$(mktemp -d); \
 	cmd="cd $(PERF) && $(MAKE_F) $($@) $(PARALLEL_OPT) $(O_OPT) DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
 	( eval $$cmd ) >> $@ 2>&1; \
@@ -320,7 +322,7 @@ $(run):
 
 make_with_gtk2:
 	$(call clean)
-	@TMP_DEST=$$(mktemp -d); \
+	+@TMP_DEST=$$(mktemp -d); \
 	cmd="cd $(PERF) && $(MAKE_F) $($@) $(PARALLEL_OPT) $(O_OPT) DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
 	( eval $$cmd ) >> $@ 2>&1; \
@@ -330,7 +332,7 @@ make_with_gtk2:
 
 make_static:
 	$(call clean)
-	@TMP_DEST=$$(mktemp -d); \
+	+@TMP_DEST=$$(mktemp -d); \
 	cmd="cd $(PERF) && $(MAKE_F) $($@) $(PARALLEL_OPT) $(O_OPT) DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
 	( eval $$cmd ) >> $@ 2>&1; \
@@ -339,8 +341,10 @@ make_static:
 	rm -rf $@ $$TMP_DEST || (cat $@ ; false)
 
 $(run_O):
+ifneq ($(O_CLEAN),0)
 	$(call clean)
-	@TMP_O=$$(mktemp -d); \
+endif
+	+@TMP_O=$$(mktemp -d); \
 	TMP_DEST=$$(mktemp -d); \
 	cmd="cd $(PERF) && $(MAKE_F) $($(patsubst %_O,%,$@)) $(PARALLEL_OPT) O=$$TMP_O DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
@@ -363,18 +367,18 @@ endif
 make_kernelsrc:
 	@echo "- make -C <kernelsrc> $(PARALLEL_OPT) $(K_O_OPT) tools/perf"
 	$(call clean); \
-	(make -C ../.. $(PARALLEL_OPT) $(K_O_OPT) tools/perf) > $@ 2>&1 && \
+	($(MAKE) -C ../.. $(PARALLEL_OPT) $(K_O_OPT) tools/perf) > $@ 2>&1 && \
 	test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false)
 
 make_kernelsrc_tools:
 	@echo "- make -C <kernelsrc>/tools $(PARALLEL_OPT) $(K_O_OPT) perf"
 	$(call clean); \
-	(make -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \
+	($(MAKE) -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \
 	test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false)
 
 make_libperf:
 	@echo "- make -C lib";
-	make -C lib clean >$@ 2>&1; make -C lib >>$@ 2>&1 && rm $@
+	$(MAKE) -C lib clean >$@ 2>&1; $(MAKE) -C lib >>$@ 2>&1 && rm $@
 
 FEATURES_DUMP_FILE := $(FULL_O)/BUILD_TEST_FEATURE_DUMP
 FEATURES_DUMP_FILE_STATIC := $(FULL_O)/BUILD_TEST_FEATURE_DUMP_STATIC
@@ -383,20 +387,22 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools
 	@echo OK
 	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
 
-out: $(run_O)
+out:
+	$(call clean)
+	@$(MAKE) -f tests/make $(run_O) PARALLEL_OPT= O_CLEAN=0 $(if $(findstring jobserver,$(MAKEFLAGS))$(findstring -j,$(MAKEFLAGS)),,$(if $(cores),-j$(cores)))
 	@echo OK
 	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
 
 ifeq ($(REUSE_FEATURES_DUMP),1)
 $(FEATURES_DUMP_FILE):
 	$(call clean)
-	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
+	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
 	echo "- $@: $$cmd" && echo $$cmd && \
 	( eval $$cmd ) > /dev/null 2>&1
 
 $(FEATURES_DUMP_FILE_STATIC):
 	$(call clean)
-	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
+	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
 	echo "- $@: $$cmd" && echo $$cmd && \
 	( eval $$cmd ) > /dev/null 2>&1
 
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] perf tests: Improvements to build-test performance
  2026-09-03  4:56 ` [PATCH v2] " Ian Rogers
@ 2026-09-03  5:04   ` sashiko-bot
  2026-09-09 16:10   ` [PATCH v3] " Ian Rogers
  1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-09-03  5:04 UTC (permalink / raw)
  To: Ian Rogers; +Cc: linux-perf-users

> Replace hardcoded 'make' calls with '$(MAKE)' within tests/make to
> ensure GNU Make jobserver file descriptors are properly inherited by
> nested builds.
> 
> Additionally, remove the 'unexport MAKEFLAGS' from
> tools/perf/Makefile. This hack was originally added to prevent the
> wrapper's internal '-j$(JOBS)' override from crashing when parent
> jobserver tokens were present. Instead, use proper GNU Make
> conditionals to check for '-j' or 'jobserver' strings within
> MAKEFLAGS. If a jobserver is already orchestrating the build,
> gracefully back off and let GNU Make manage parallelism natively.
> 
> Finally, optimize the 'out' target (which processes 'run_O'
> out-of-tree builds) by stripping sequential bottlenecks like $(call
> clean) from isolated tmp directories, and wrapping the target list in
> a parallel sub-make call.
> 
> These combined changes enable 'build-test' out-of-tree targets to
> build completely concurrently without severing jobserver tokens.
> 
> Unscientifically measured the change lowered the build-test from
> around 15 minutes to 10 minutes on a 28 threaded Alderlake CPU. Fixing
> the jobserver issues meant the machine remained somewhat usable while
> running the test.
> 
> Signed-off-by: Ian Rogers <irogers@google.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260903045603.3611902-1-irogers@google.com?part=1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3] perf tests: Improvements to build-test performance
  2026-09-03  4:56 ` [PATCH v2] " Ian Rogers
  2026-09-03  5:04   ` sashiko-bot
@ 2026-09-09 16:10   ` Ian Rogers
  2026-09-09 16:21     ` sashiko-bot
  1 sibling, 1 reply; 7+ messages in thread
From: Ian Rogers @ 2026-09-09 16:10 UTC (permalink / raw)
  To: irogers, acme, linux-perf-users, namhyung
  Cc: adrian.hunter, james.clark, jolsa, leo.yan, linux-kernel, mingo,
	mjeanson, peterz

Replace hardcoded 'make' calls with '$(MAKE)' within tests/make
to ensure GNU Make jobserver file descriptors are properly inherited
by nested builds.

Additionally, remove the notorious 'unexport MAKEFLAGS' from
tools/perf/Makefile. This hack was originally added to prevent
the wrapper's internal '-j$(JOBS)' override from crashing when parent
jobserver tokens were present. Instead, use proper GNU Make conditionals
to check for '-j' or 'jobserver' strings within MAKEFLAGS. If a jobserver
is already orchestrating the build, gracefully back off and let GNU Make
manage parallelism natively.

Finally, optimize the 'out' target (which processes 'run_O' out-of-tree
builds) by stripping sequential bottlenecks like $(call clean) from
isolated tmp directories, and wrapping the target list in a parallel
sub-make call.

These combined changes enable 'build-test' out-of-tree targets to
build completely concurrently without severing jobserver tokens.

Unscientifically measured the change lowered the build-test from
around 15 minutes to 10 minutes on a 28 threaded Alderlake CPU. Fixing
the jobserver issues meant the machine remained somewhat usable while
running the test.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro

---
v3:
 - Added order-only tracking for make_tags_O and make_cscope_O against
   make_clean_all_O. By parallelizing the 'out' tests in v2, make_clean_all
   was sporadically deleting the source tree's './tags' file mid-sort while
   make_tags executed concurrently alongside it, resulting in ctags crashes.
 - Added explicit trap cleanup routines via bash to properly emulate standard
   GNU Make behavior on SIGINT/SIGTERM. If a user interrupts the test
   using Ctrl+C, files like 'make_debug_O' and temporal build folders get
   properly cleaned up. They are only left behind if the test errors out.
v2:
 - Re-structured build-test array in tools/perf/Makefile into explicit
   sequential $(MAKE) passes. This prevents in-tree targets (make_static,
   etc.) from racing to directory corruption when exposed to native
   jobservers.
 - Added '+' prefix to recipe modifiers in tests/make to prevent jobserver
   FDs from being stripped before sub-shell evaluation.
 - Replaced hardcoded -j$(cores) limits in the 'out' sub-make step with
   dynamic jobserver boundary detection to prevent fork-bomb override
   collisions.
 - Restored missing $(call clean) steps via O_CLEAN conditionals to prevent
   in-tree polluted runs from breaking out-of-tree sequences.
 - Removed unconditionally appended $(FEATURES_DUMP_FILE) target restrictions
   from 'out' that threw "No rule to make target" errors on unhandled tests.
 - Fixed 'test_dest_files' to check [ ! -f ] instead of [ ! -x ], removing
   long-standing ghost warnings for non-executable mode-644 targets
   like etc/bash_completion.d/perf.
 - Fixed cosmetic string formatting bugs in GNU Make's print_msg banner
   output.
---
 tools/perf/Makefile   | 35 +++++++++++++++++++-----------
 tools/perf/tests/make | 50 +++++++++++++++++++++++++++----------------
 2 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 5b713837eede..2cbf4cb5f093 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -14,23 +14,29 @@
 .SUFFIXES:
 
 #
-# We don't want to pass along options like -j:
+# If no parallel build was requested, do a parallel build with multiple jobs,
+# based on the number of CPUs online in this system: 'make -j8' on an 8-CPU
+# system, etc.
 #
-unexport MAKEFLAGS
-
-#
-# Do a parallel build with multiple jobs, based on the number of CPUs online
-# in this system: 'make -j8' on a 8-CPU system, etc.
+# If MAKEFLAGS contains '-j' or 'jobserver', JOBS is intentionally left
+# uninitialized so the native GNU Make jobserver can seamlessly control the
+# parallel bounds of the build.
 #
 # (To override it, run 'make JOBS=1' and similar.)
 #
-ifeq ($(JOBS),)
-  JOBS := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
-  ifeq ($(JOBS),0)
-    JOBS := 1
+ifeq ($(findstring -j,$(MAKEFLAGS)),)
+  ifeq ($(findstring jobserver,$(MAKEFLAGS)),)
+    ifeq ($(JOBS),)
+      JOBS := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
+      ifeq ($(JOBS),0)
+        JOBS := 1
+      endif
+    endif
+    PARALLEL_OPT := -j$(JOBS)
   endif
 endif
 
+
 #
 # Only pass canonical directory names as the output directory:
 #
@@ -58,11 +64,11 @@ else
 endif
 
 define print_msg
-  @printf '  BUILD:   Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' $(BUILD_TYPE) build\n'
+  @printf '  BUILD:   Doing '\''make\033[33m%s\033[m'\'' $(BUILD_TYPE) build\n' "$(if $(JOBS), -j$(JOBS),)"
 endef
 
 define make
-  @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $(SET_DEBUG) $@
+  @$(MAKE) -f Makefile.perf --no-print-directory $(PARALLEL_OPT) O=$(FULL_O) $(SET_DEBUG) $@
 endef
 
 #
@@ -106,7 +112,10 @@ clean:
 # make -C tools/perf -f tests/make
 #
 build-test:
-	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory tarpkg make_static make_with_gtk2 out
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory tarpkg
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory make_static
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory make_with_gtk2
+	@$(MAKE) SHUF=1 -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory out
 
 build-test-tarball:
 	@$(MAKE) -f tests/make REUSE_FEATURES_DUMP=1 MK=Makefile SET_PARALLEL=1 --no-print-directory out
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index d2c2f526e1db..4a865e58f2be 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -28,15 +28,17 @@ endif
 
 PARALLEL_OPT=
 ifeq ($(SET_PARALLEL),1)
-  ifeq ($(JOBS),)
-    cores := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
-    ifeq ($(cores),0)
-      cores := 1
+  ifeq ($(findstring jobserver,$(MAKEFLAGS))$(findstring -j,$(MAKEFLAGS)),)
+    ifeq ($(JOBS),)
+      cores := $(shell (getconf _NPROCESSORS_ONLN || grep -E -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
+      ifeq ($(cores),0)
+        cores := 1
+      endif
+    else
+      cores=$(JOBS)
     endif
-  else
-    cores=$(JOBS)
+    PARALLEL_OPT="-j$(cores)"
   endif
-  PARALLEL_OPT="-j$(cores)"
 endif
 
 # As per kernel Makefile, avoid funny character set dependencies
@@ -230,7 +232,7 @@ test_make_util_pmu_bison_o := test -f $(PERF_O)/util/pmu-bison.o
 
 define test_dest_files
   for file in $(1); do				\
-    if [ ! -x $$TMP_DEST/$$file ]; then		\
+    if [ ! -f $$TMP_DEST/$$file ]; then		\
       echo "  failed to find: $$file";		\
     fi						\
   done
@@ -310,7 +312,8 @@ clean := @(cd $(PERF); $(MAKE_F) -s $(O_OPT) clean >/dev/null && $(MAKE) -s $(O_
 
 $(run):
 	$(call clean)
-	@TMP_DEST=$$(mktemp -d); \
+	+@TMP_DEST=$$(mktemp -d); \
+	trap 'rm -rf $@ $$TMP_DEST; exit 130' INT TERM; \
 	cmd="cd $(PERF) && $(MAKE_F) $($@) $(PARALLEL_OPT) $(O_OPT) DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
 	( eval $$cmd ) >> $@ 2>&1; \
@@ -320,7 +323,8 @@ $(run):
 
 make_with_gtk2:
 	$(call clean)
-	@TMP_DEST=$$(mktemp -d); \
+	+@TMP_DEST=$$(mktemp -d); \
+	trap 'rm -rf $@ $$TMP_DEST; exit 130' INT TERM; \
 	cmd="cd $(PERF) && $(MAKE_F) $($@) $(PARALLEL_OPT) $(O_OPT) DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
 	( eval $$cmd ) >> $@ 2>&1; \
@@ -330,7 +334,8 @@ make_with_gtk2:
 
 make_static:
 	$(call clean)
-	@TMP_DEST=$$(mktemp -d); \
+	+@TMP_DEST=$$(mktemp -d); \
+	trap 'rm -rf $@ $$TMP_DEST; exit 130' INT TERM; \
 	cmd="cd $(PERF) && $(MAKE_F) $($@) $(PARALLEL_OPT) $(O_OPT) DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
 	( eval $$cmd ) >> $@ 2>&1; \
@@ -339,9 +344,12 @@ make_static:
 	rm -rf $@ $$TMP_DEST || (cat $@ ; false)
 
 $(run_O):
+ifneq ($(O_CLEAN),0)
 	$(call clean)
-	@TMP_O=$$(mktemp -d); \
+endif
+	+@TMP_O=$$(mktemp -d); \
 	TMP_DEST=$$(mktemp -d); \
+	trap 'rm -rf $@ $$TMP_O $$TMP_DEST; exit 130' INT TERM; \
 	cmd="cd $(PERF) && $(MAKE_F) $($(patsubst %_O,%,$@)) $(PARALLEL_OPT) O=$$TMP_O DESTDIR=$$TMP_DEST"; \
 	printf "%*.*s: %s\n" $(max_width) $(max_width) "$@" "$$cmd" && echo $$cmd > $@ && \
 	( eval $$cmd ) >> $@ 2>&1 && \
@@ -363,18 +371,18 @@ endif
 make_kernelsrc:
 	@echo "- make -C <kernelsrc> $(PARALLEL_OPT) $(K_O_OPT) tools/perf"
 	$(call clean); \
-	(make -C ../.. $(PARALLEL_OPT) $(K_O_OPT) tools/perf) > $@ 2>&1 && \
+	($(MAKE) -C ../.. $(PARALLEL_OPT) $(K_O_OPT) tools/perf) > $@ 2>&1 && \
 	test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false)
 
 make_kernelsrc_tools:
 	@echo "- make -C <kernelsrc>/tools $(PARALLEL_OPT) $(K_O_OPT) perf"
 	$(call clean); \
-	(make -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \
+	($(MAKE) -C ../../tools $(PARALLEL_OPT) $(K_O_OPT) perf) > $@ 2>&1 && \
 	test -x $(KERNEL_O)/tools/perf/perf && rm -f $@ || (cat $@ ; false)
 
 make_libperf:
 	@echo "- make -C lib";
-	make -C lib clean >$@ 2>&1; make -C lib >>$@ 2>&1 && rm $@
+	$(MAKE) -C lib clean >$@ 2>&1; $(MAKE) -C lib >>$@ 2>&1 && rm $@
 
 FEATURES_DUMP_FILE := $(FULL_O)/BUILD_TEST_FEATURE_DUMP
 FEATURES_DUMP_FILE_STATIC := $(FULL_O)/BUILD_TEST_FEATURE_DUMP_STATIC
@@ -383,20 +391,22 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools
 	@echo OK
 	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
 
-out: $(run_O)
+out:
+	$(call clean)
+	@$(MAKE) -f tests/make $(run_O) PARALLEL_OPT= O_CLEAN=0 $(if $(findstring jobserver,$(MAKEFLAGS))$(findstring -j,$(MAKEFLAGS)),,$(if $(cores),-j$(cores)))
 	@echo OK
 	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
 
 ifeq ($(REUSE_FEATURES_DUMP),1)
 $(FEATURES_DUMP_FILE):
 	$(call clean)
-	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
+	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
 	echo "- $@: $$cmd" && echo $$cmd && \
 	( eval $$cmd ) > /dev/null 2>&1
 
 $(FEATURES_DUMP_FILE_STATIC):
 	$(call clean)
-	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
+	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
 	echo "- $@: $$cmd" && echo $$cmd && \
 	( eval $$cmd ) > /dev/null 2>&1
 
@@ -416,3 +426,7 @@ endif
 
 .PHONY: all $(run) $(run_O) tarpkg clean make_kernelsrc make_kernelsrc_tools make_libperf
 endif # ifndef MK
+
+# Serialize execution of tasks writing to shared in-tree files
+make_tags_O: | make_clean_all_O
+make_cscope_O: | make_clean_all_O
-- 
2.55.0.979.g7e5102b832-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] perf tests: Improvements to build-test performance
  2026-09-09 16:10   ` [PATCH v3] " Ian Rogers
@ 2026-09-09 16:21     ` sashiko-bot
  2026-09-09 17:38       ` Ian Rogers
  0 siblings, 1 reply; 7+ messages in thread
From: sashiko-bot @ 2026-09-09 16:21 UTC (permalink / raw)
  To: Ian Rogers; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The parallelization of the `out` target causes destructive races between `FEATURES_DUMP_FILE` and `FEATURES_DUMP_FILE_STATIC` within the shared source tree.
--

commit 8a5611d5732e412e746570eca199bea2894c319b
Author: Ian Rogers <irogers@google.com>

perf tests: Improvements to build-test performance

This patch replaces hardcoded 'make' calls with '$(MAKE)' in the perf tests
Makefile to ensure proper GNU Make jobserver file descriptor inheritance. It
also removes 'unexport MAKEFLAGS' in favor of native GNU Make conditionals
for parallelism. Finally, it optimizes the 'out' target by wrapping the target
list in a parallel sub-make call.

> diff --git a/tools/perf/tests/make b/tools/perf/tests/make
> index d2c2f526e1db0..4a865e58f2bea 100644
> --- a/tools/perf/tests/make
> +++ b/tools/perf/tests/make
[ ... ]
> @@ -383,20 +391,22 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools
>  	@echo OK
>  	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
>  
> -out: $(run_O)
> +out:
> +	$(call clean)
> +	@$(MAKE) -f tests/make $(run_O) PARALLEL_OPT= O_CLEAN=0 $(if $(findstring jobserver,$(MAKEFLAGS))$(findstring -j,$(MAKEFLAGS)),,$(if $(cores),-j$(cores)))

[Severity: Medium]
When the out target invokes this parallel sub-make for all run_O targets, does
this expose the feature dump dependencies to concurrent evaluation?

>  	@echo OK
>  	@rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
>  
>  ifeq ($(REUSE_FEATURES_DUMP),1)
>  $(FEATURES_DUMP_FILE):
>  	$(call clean)
> -	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
> +	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
>  	echo "- $@: $$cmd" && echo $$cmd && \
>  	( eval $$cmd ) > /dev/null 2>&1
>  
>  $(FEATURES_DUMP_FILE_STATIC):
>  	$(call clean)
> -	@cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
> +	@cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \

[Severity: Medium]
Will these feature dump recipes race destructively?

Since some run_O targets like make_static_O depend on
FEATURES_DUMP_FILE_STATIC while others depend on FEATURES_DUMP_FILE,
evaluating them concurrently means both unconditionally invoke make clean and
make feature-dump inside the shared source tree.

Could this cause them to wipe out each other's intermediate artifacts during
make build-test out-of-tree builds?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260909161041.1745638-1-irogers@google.com?part=1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] perf tests: Improvements to build-test performance
  2026-09-09 16:21     ` sashiko-bot
@ 2026-09-09 17:38       ` Ian Rogers
  0 siblings, 0 replies; 7+ messages in thread
From: Ian Rogers @ 2026-09-09 17:38 UTC (permalink / raw)
  To: sashiko-reviews, linux-perf-users

On Wed, Sep 9, 2026 at 9:21 AM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] The parallelization of the `out` target causes destructive races between `FEATURES_DUMP_FILE` and `FEATURES_DUMP_FILE_STATIC` within the shared source tree.
> --
>
> commit 8a5611d5732e412e746570eca199bea2894c319b
> Author: Ian Rogers <irogers@google.com>
>
> perf tests: Improvements to build-test performance
>
> This patch replaces hardcoded 'make' calls with '$(MAKE)' in the perf tests
> Makefile to ensure proper GNU Make jobserver file descriptor inheritance. It
> also removes 'unexport MAKEFLAGS' in favor of native GNU Make conditionals
> for parallelism. Finally, it optimizes the 'out' target by wrapping the target
> list in a parallel sub-make call.
>
> > diff --git a/tools/perf/tests/make b/tools/perf/tests/make
> > index d2c2f526e1db0..4a865e58f2bea 100644
> > --- a/tools/perf/tests/make
> > +++ b/tools/perf/tests/make
> [ ... ]
> > @@ -383,20 +391,22 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools
> >       @echo OK
> >       @rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
> >
> > -out: $(run_O)
> > +out:
> > +     $(call clean)
> > +     @$(MAKE) -f tests/make $(run_O) PARALLEL_OPT= O_CLEAN=0 $(if $(findstring jobserver,$(MAKEFLAGS))$(findstring -j,$(MAKEFLAGS)),,$(if $(cores),-j$(cores)))
>
> [Severity: Medium]
> When the out target invokes this parallel sub-make for all run_O targets, does
> this expose the feature dump dependencies to concurrent evaluation?
>
> >       @echo OK
> >       @rm -f $(FEATURES_DUMP_FILE) $(FEATURES_DUMP_FILE_STATIC)
> >
> >  ifeq ($(REUSE_FEATURES_DUMP),1)
> >  $(FEATURES_DUMP_FILE):
> >       $(call clean)
> > -     @cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
> > +     @cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) feature-dump"; \
> >       echo "- $@: $$cmd" && echo $$cmd && \
> >       ( eval $$cmd ) > /dev/null 2>&1
> >
> >  $(FEATURES_DUMP_FILE_STATIC):
> >       $(call clean)
> > -     @cmd="cd $(PERF) && make FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
> > +     @cmd="cd $(PERF) && $(MAKE) FEATURE_DUMP_COPY=$@ $(O_OPT) LDFLAGS='-static' feature-dump"; \
>
> [Severity: Medium]
> Will these feature dump recipes race destructively?
>
> Since some run_O targets like make_static_O depend on
> FEATURES_DUMP_FILE_STATIC while others depend on FEATURES_DUMP_FILE,
> evaluating them concurrently means both unconditionally invoke make clean and
> make feature-dump inside the shared source tree.
>
> Could this cause them to wipe out each other's intermediate artifacts during
> make build-test out-of-tree builds?

As make_static isn't part of the "run" variable set of tests it won't
be part of run_O created by the foreach loop. make_static is only ever
run sequentially and so there can't be concurrent evaluation of
FEATURES_DUMP_FILE_STATIC.

Thanks,
Ian

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-09-09 17:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 15:31 [PATCH v1] perf tests: Improvements to build-test performance Ian Rogers
2026-09-02 15:40 ` sashiko-bot
2026-09-03  4:56 ` [PATCH v2] " Ian Rogers
2026-09-03  5:04   ` sashiko-bot
2026-09-09 16:10   ` [PATCH v3] " Ian Rogers
2026-09-09 16:21     ` sashiko-bot
2026-09-09 17:38       ` Ian Rogers

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.