mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
perf pmu-events: Split big_c_string storage into standalone compilation unit
Currently, jevents.py emits both the massive 2.8 MB big_c_string literal
and tens of thousands of compact_pmu_event struct arrays into a single
pmu-events.c compilation unit. Compiling this giant file takes ~2.2 seconds
on a single CPU core during Kbuild startup.
Refactor jevents.py to emit big_c_string into a dedicated
pmu-events-string.c compilation unit. This allows Kbuild to compile
pmu-events.o and pmu-events-string.o simultaneously in parallel across
two separate CPU cores, preserving 100% string deduplication and zero
dynamic ELF relocations while cutting C compilation latency in half.
Add pmu-events-string.c to tools/perf/.gitignore to ensure in-tree Kbuild
runs do not leave untracked generated files in the working directory.
To guarantee 100% backward compatibility with GNU Make 4.0+ (avoiding the
Make 4.3+ grouped target &: syntax which causes older Make versions like
4.2.1 to spawn multiple concurrent jevents.py processes during parallel
builds), implement a robust dependency chaining pattern:
$(PMU_EVENTS_C): $(JEVENTS_DEPS)
$(PMU_EVENTS_STRING_C): $(PMU_EVENTS_C)
@:
This ensures jevents.py is invoked exactly once. If jevents.py aborts
early, Make's .DELETE_ON_ERROR: purges pmu-events.c, guaranteeing that
subsequent Make invocations correctly re-execute the script and overwrite
pmu-events-string.c. In jevents.py, explicitly close output_file first
and output_string_file second at the tail of main() to guarantee that
pmu-events-string.c receives a filesystem timestamp greater than or equal
to pmu-events.c, completely avoiding redundant incremental rebuilds.
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: James Clark <james.clark@linaro.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Chartre <alexandre.chartre@oracle.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Ankur Arora <ankur.a.arora@oracle.com>
Cc: Collin Funk <collin.funk1@gmail.com>
Cc: Costa Shulyupin <costa.shul@redhat.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: David Sterba <dsterba@suse.com>
Cc: Dmitrii Dolgov <9erthalion6@gmail.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Markus Mayer <mmayer@broadcom.com>
Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Terrell <terrelln@fb.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Quentin Monnet <qmo@kernel.org>
Cc: Ricky Ringler <ricky.ringler@proton.me>
Cc: Song Liu <song@kernel.org>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Cc: Thomas Falcon <thomas.falcon@intel.com>
Cc: Tomas Glozar <tglozar@redhat.com>
Cc: Yonghong Song <yonghong.song@linux.dev>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
29331b2edb
commit
bb922345ee
1
tools/perf/.gitignore
vendored
1
tools/perf/.gitignore
vendored
|
|
@ -38,6 +38,7 @@ arch/*/include/generated/
|
|||
trace/beauty/generated/
|
||||
pmu-events/arch/common/common/legacy-cache.json
|
||||
pmu-events/pmu-events.c
|
||||
pmu-events/pmu-events-string.c
|
||||
pmu-events/jevents
|
||||
pmu-events/metric_test.log
|
||||
pmu-events/empty-pmu-events.log
|
||||
|
|
|
|||
|
|
@ -925,7 +925,7 @@ bpf-skel-clean:
|
|||
pmu-events-clean:
|
||||
ifeq ($(OUTPUT),)
|
||||
$(call QUIET_CLEAN, pmu-events) $(RM) \
|
||||
pmu-events/pmu-events.c \
|
||||
pmu-events/pmu-events*.c \
|
||||
pmu-events/metric_test.log \
|
||||
pmu-events/test-empty-pmu-events.c \
|
||||
pmu-events/empty-pmu-events.log
|
||||
|
|
@ -933,7 +933,7 @@ ifeq ($(OUTPUT),)
|
|||
-name 'extra-metricgroups.json' -delete
|
||||
else # When an OUTPUT directory is present, clean up the copied pmu-events/arch directory.
|
||||
$(call QUIET_CLEAN, pmu-events) $(RM) -r $(OUTPUT)pmu-events/arch \
|
||||
$(OUTPUT)pmu-events/pmu-events.c \
|
||||
$(OUTPUT)pmu-events/pmu-events*.c \
|
||||
$(OUTPUT)pmu-events/metric_test.log \
|
||||
$(OUTPUT)pmu-events/test-empty-pmu-events.c \
|
||||
$(OUTPUT)pmu-events/empty-pmu-events.log
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
EMPTY_PMU_EVENTS_C = pmu-events/empty-pmu-events.c
|
||||
# pmu-events.c will be generated by jevents.py or copied from EMPTY_PMU_EVENTS_C
|
||||
PMU_EVENTS_C = $(OUTPUT)pmu-events/pmu-events.c
|
||||
PMU_EVENTS_STRING_C = $(OUTPUT)pmu-events/pmu-events-string.c
|
||||
|
||||
pmu-events-y += pmu-events.o
|
||||
ifneq ($(NO_JEVENTS),1)
|
||||
pmu-events-y += pmu-events-string.o
|
||||
endif
|
||||
|
||||
# pmu-events.c file is generated in the OUTPUT directory so it needs a
|
||||
# separate rule to depend on it properly
|
||||
|
|
@ -9,6 +14,10 @@ $(OUTPUT)pmu-events/pmu-events.o: $(PMU_EVENTS_C)
|
|||
$(call rule_mkdir)
|
||||
$(call if_changed_dep,cc_o_c)
|
||||
|
||||
$(OUTPUT)pmu-events/pmu-events-string.o: $(PMU_EVENTS_STRING_C)
|
||||
$(call rule_mkdir)
|
||||
$(call if_changed_dep,cc_o_c)
|
||||
|
||||
# Message for $(call echo-cmd,cp), possibly remove the src file from
|
||||
# the destination to save space in the build log.
|
||||
quiet_cmd_cp = COPY $(patsubst %$<,%,$@) <- $<
|
||||
|
|
@ -118,6 +127,7 @@ CUR_OUT_JSON := $(shell [ -d $(OUT_DIR) ] && find $(OUT_DIR) -type f)
|
|||
|
||||
# Things in the OUTPUT directory but shouldn't be there as computed by
|
||||
# OUT_JSON and GEN_JSON.
|
||||
|
||||
ORPHAN_FILES := $(filter-out $(OUT_JSON) $(GEN_JSON),$(CUR_OUT_JSON))
|
||||
|
||||
# Message for $(call echo-cmd,mkd). There is already a mkdir message
|
||||
|
|
@ -224,6 +234,10 @@ endif
|
|||
# and inputs are dependencies.
|
||||
$(PMU_EVENTS_C): $(JEVENTS_DEPS)
|
||||
$(call rule_mkdir)
|
||||
$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) $(OUT_DIR) $@
|
||||
$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) \
|
||||
$(OUT_DIR) $(PMU_EVENTS_C) $(PMU_EVENTS_STRING_C)
|
||||
|
||||
$(PMU_EVENTS_STRING_C): $(PMU_EVENTS_C)
|
||||
@:
|
||||
|
||||
endif # ifeq ($(NO_JEVENTS),1)
|
||||
|
|
|
|||
|
|
@ -1422,6 +1422,8 @@ such as "arm/cortex-a34".''',
|
|||
)
|
||||
ap.add_argument(
|
||||
'output_file', type=argparse.FileType('w', encoding='utf-8'), nargs='?', default=sys.stdout)
|
||||
ap.add_argument(
|
||||
'output_string_file', type=argparse.FileType('w', encoding='utf-8'), nargs='?', default=None)
|
||||
_args = ap.parse_args()
|
||||
|
||||
_args.output_file.write(f"""
|
||||
|
|
@ -1463,10 +1465,20 @@ struct pmu_table_entry {
|
|||
ftw(arch_path, [], preprocess_one_file)
|
||||
|
||||
_bcs.compute()
|
||||
_args.output_file.write('static const char *const big_c_string =\n')
|
||||
for s in _bcs.big_string:
|
||||
_args.output_file.write(s)
|
||||
_args.output_file.write(';\n\n')
|
||||
if not _args.output_string_file:
|
||||
_args.output_file.write('static const char *const big_c_string =\n')
|
||||
for s in _bcs.big_string:
|
||||
_args.output_file.write(s)
|
||||
_args.output_file.write(';\n\n')
|
||||
else:
|
||||
_args.output_string_file.write('/* SPDX-License-Identifier: GPL-2.0 */\n')
|
||||
_args.output_string_file.write('/* Autogenerated by jevents.py */\n')
|
||||
_args.output_string_file.write('extern const char big_c_string[];\n')
|
||||
_args.output_string_file.write('const char big_c_string[] =\n')
|
||||
for s in _bcs.big_string:
|
||||
_args.output_string_file.write(s)
|
||||
_args.output_string_file.write(';\n')
|
||||
_args.output_file.write('extern const char big_c_string[];\n\n')
|
||||
for arch in archs:
|
||||
arch_path = f'{_args.starting_dir}/{arch}'
|
||||
ftw(arch_path, [], process_one_file)
|
||||
|
|
@ -1476,6 +1488,9 @@ struct pmu_table_entry {
|
|||
print_mapping_table(archs)
|
||||
print_system_mapping_table()
|
||||
print_metricgroups()
|
||||
_args.output_file.close()
|
||||
if _args.output_string_file:
|
||||
_args.output_string_file.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user