From 23e0a63c6dd3f69cb7ee18411e5f6857cca55b30 Mon Sep 17 00:00:00 2001 From: Anubhav Shelat Date: Fri, 31 Jan 2025 09:57:05 -0500 Subject: perf script: force stdin for flamegraph in live mode Currently, running "perf script flamegraph -a -F 99 sleep 1" should produce flamegraph.html containing the flamegraph. Howevever, it gives a segmentation fault. This is caused because the flamegraph.py script is supposed to take as input the output of "perf record", which should be in stdin. This would require passing "-i -" to flamegraph.py. However, the "flamegraph-report" script causes "perf script" command to take the "-i -" option instead of flamegraph.py, which causes no problem for "perf script", but causes a seg fault since flamegraph.py has no input file. To fix this I added the "-i -" option directly to the flamegraph-report script to ensure flamegraph.py gets input from stdin. Signed-off-by: Anubhav Shelat Tested-by: Michael Petlan Link: https://lore.kernel.org/r/20250131145704.3164542-2-ashelat@redhat.com Signed-off-by: Namhyung Kim --- tools/perf/scripts/python/bin/flamegraph-report | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/scripts') diff --git a/tools/perf/scripts/python/bin/flamegraph-report b/tools/perf/scripts/python/bin/flamegraph-report index 53c5dc90c87e..83d5738c75ca 100755 --- a/tools/perf/scripts/python/bin/flamegraph-report +++ b/tools/perf/scripts/python/bin/flamegraph-report @@ -1,3 +1,3 @@ #!/bin/bash # description: create flame graphs -perf script -s "$PERF_EXEC_PATH"/scripts/python/flamegraph.py -- "$@" +perf script -s "$PERF_EXEC_PATH"/scripts/python/flamegraph.py -i - -- "$@" -- cgit v1.2.3 From 29bab85418efd329c1a984fc9b885b6709481b27 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 18 Feb 2025 16:05:58 -0800 Subject: perf script: Fix hangup in offline flamegraph report A recent change in the flamegraph script fixed an issue with live mode but it created another for offline mode. It needs to pass "-" to -i option to read from stdin in the live mode. Actually there's a logic to pass the option in the perf script code, but the script was written with "-- $@" which prevented the option to go to the perf script. So the previous commit added the hard-coded "-i -" to the report command. But it's a problem for the offline mode which expects input from a file and now it's stuck on reading from stdin. Let's remove the "-i - --" part and let it pass the options properly to perf script. Closes: https://lore.kernel.org/linux-perf-users/c41e4b04-e1fd-45ab-80b0-ec2ac6e94310@linux.ibm.com Fixes: 23e0a63c6dd3f69c ("perf script: force stdin for flamegraph in live mode") Reported-by: Thomas Richter Tested-by: Thomas Richter Cc: Anubhav Shelat Signed-off-by: Namhyung Kim --- tools/perf/scripts/python/bin/flamegraph-report | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/scripts') diff --git a/tools/perf/scripts/python/bin/flamegraph-report b/tools/perf/scripts/python/bin/flamegraph-report index 83d5738c75ca..453a6918afbe 100755 --- a/tools/perf/scripts/python/bin/flamegraph-report +++ b/tools/perf/scripts/python/bin/flamegraph-report @@ -1,3 +1,3 @@ #!/bin/bash # description: create flame graphs -perf script -s "$PERF_EXEC_PATH"/scripts/python/flamegraph.py -i - -- "$@" +perf script -s "$PERF_EXEC_PATH"/scripts/python/flamegraph.py "$@" -- cgit v1.2.3 From 5c2938fe789c1876a35a1fbc24da3800b33adf26 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 18 Mar 2025 22:07:32 -0700 Subject: perf syscalltbl: Remove struct syscalltbl The syscalltbl held entries of system call name and number pairs, generated from a native syscalltbl at start up. As there are gaps in the system call number there is a notion of index into the table. Going forward we want the system call table to be identifiable by a machine type, for example, i386 vs x86-64. Change the interface to the syscalltbl so (1) a (currently unused machine type of EM_HOST) is passed (2) the index to syscall number and system call name mapping is computed at build time. Two tables are used for this, an array of system call number to name, an array of system call numbers sorted by the system call name. The sorted array doesn't store strings in part to save memory and relocations. The index notion is carried forward and is an index into the sorted array of system call numbers, the data structures are opaque (held only in syscalltbl.c), and so the number of indices for a machine type is exposed as a new API. The arrays are computed in the syscalltbl.sh script and so no start-up time computation and storage is necessary. Signed-off-by: Ian Rogers Reviewed-by: Howard Chu Reviewed-by: Charlie Jenkins Reviewed-by: Namhyung Kim Acked-by: Arnaldo Carvalho de Melo Link: https://lore.kernel.org/r/20250319050741.269828-6-irogers@google.com Signed-off-by: Namhyung Kim --- tools/perf/scripts/syscalltbl.sh | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) (limited to 'tools/perf/scripts') diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh index 1ce0d5aa8b50..a39b3013b103 100755 --- a/tools/perf/scripts/syscalltbl.sh +++ b/tools/perf/scripts/syscalltbl.sh @@ -50,37 +50,27 @@ fi infile="$1" outfile="$2" -nxt=0 - -syscall_macro() { - nr="$1" - name="$2" - - echo " [$nr] = \"$name\"," -} - -emit() { - nr="$1" - entry="$2" - - syscall_macro "$nr" "$entry" -} - -echo "static const char *const syscalltbl[] = {" > $outfile - sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX) grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table -max_nr=0 +echo "static const char *const syscall_num_to_name[] = {" > $outfile # the params are: nr abi name entry compat # use _ for intentionally unused variables according to SC2034 while read nr _ name _ _; do - emit "$nr" "$name" >> $outfile - max_nr=$nr + echo " [$nr] = \"$name\"," >> $outfile done < $sorted_table +echo "};" >> $outfile -rm -f $sorted_table +echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile +# When sorting by name, add a suffix of 0s upto 20 characters so that system +# calls that differ with a numerical suffix don't sort before those +# without. This default behavior of sort differs from that of strcmp used at +# runtime. Use sed to strip the trailing 0s suffix afterwards. +grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > $sorted_table +while read name nr; do + echo " $nr, /* $name */" >> $outfile +done < $sorted_table echo "};" >> $outfile -echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile +rm -f $sorted_table -- cgit v1.2.3 From 16ab5c708d9980464a0e034f6eccdece8cbe2dae Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 18 Mar 2025 22:07:37 -0700 Subject: perf build: Remove Makefile.syscalls Now a single beauty file is generated and used by all architectures, remove the per-architecture Makefiles, Kbuild files and previous generator script. Note: there was conversation with Charlie Jenkins and they'd written an alternate approach to support multiple architectures: https://lore.kernel.org/all/20250114-perf_syscall_arch_runtime-v1-1-5b304e408e11@rivosinc.com/ It would have been better to have helped Charlie fix their series (my apologies) but they agreed that the approach taken here was likely best for longer term maintainability: https://lore.kernel.org/lkml/Z6Jk_UN9i69QGqUj@ghost/ Signed-off-by: Ian Rogers Reviewed-by: Howard Chu Reviewed-by: Charlie Jenkins Reviewed-by: Namhyung Kim Acked-by: Arnaldo Carvalho de Melo Link: https://lore.kernel.org/r/20250319050741.269828-11-irogers@google.com Signed-off-by: Namhyung Kim --- tools/perf/scripts/Makefile.syscalls | 61 ----------------------------- tools/perf/scripts/syscalltbl.sh | 76 ------------------------------------ 2 files changed, 137 deletions(-) delete mode 100644 tools/perf/scripts/Makefile.syscalls delete mode 100755 tools/perf/scripts/syscalltbl.sh (limited to 'tools/perf/scripts') diff --git a/tools/perf/scripts/Makefile.syscalls b/tools/perf/scripts/Makefile.syscalls deleted file mode 100644 index 8bf55333262e..000000000000 --- a/tools/perf/scripts/Makefile.syscalls +++ /dev/null @@ -1,61 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# This Makefile generates headers in -# tools/perf/arch/$(SRCARCH)/include/generated/asm from the architecture's -# syscall table. This will either be from the generic syscall table, or from a -# table that is specific to that architecture. - -PHONY := all -all: - -obj := $(OUTPUT)arch/$(SRCARCH)/include/generated/asm - -syscall_abis_32 := common,32 -syscall_abis_64 := common,64 -syscalltbl := $(srctree)/tools/scripts/syscall.tbl - -# let architectures override $(syscall_abis_%) and $(syscalltbl) --include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Makefile.syscalls -include $(srctree)/tools/build/Build.include --include $(srctree)/tools/perf/arch/$(SRCARCH)/entry/syscalls/Kbuild - -systbl := $(srctree)/tools/perf/scripts/syscalltbl.sh - -syscall-y := $(addprefix $(obj)/, $(syscall-y)) - -# Remove stale wrappers when the corresponding files are removed from generic-y -old-headers := $(wildcard $(obj)/*.h) -unwanted := $(filter-out $(syscall-y),$(old-headers)) - -quiet_cmd_remove = REMOVE $(unwanted) - cmd_remove = rm -f $(unwanted) - -quiet_cmd_systbl = SYSTBL $@ - cmd_systbl = $(CONFIG_SHELL) $(systbl) \ - $(if $(systbl-args-$*),$(systbl-args-$*),$(systbl-args)) \ - --abis $(subst $(space),$(comma),$(strip $(syscall_abis_$*))) \ - $< $@ - -all: $(syscall-y) - $(if $(unwanted),$(call cmd,remove)) - @: - -$(obj)/syscalls_%.h: $(syscalltbl) $(systbl) FORCE - $(call if_changed,systbl) - -targets := $(syscall-y) - -# Create output directory. Skip it if at least one old header exists -# since we know the output directory already exists. -ifeq ($(old-headers),) -$(shell mkdir -p $(obj)) -endif - -PHONY += FORCE - -FORCE: - -existing-targets := $(wildcard $(sort $(targets))) - --include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) - -.PHONY: $(PHONY) diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh deleted file mode 100755 index a39b3013b103..000000000000 --- a/tools/perf/scripts/syscalltbl.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 -# -# Generate a syscall table header. -# -# Each line of the syscall table should have the following format: -# -# NR ABI NAME [NATIVE] [COMPAT] -# -# NR syscall number -# ABI ABI name -# NAME syscall name -# NATIVE native entry point (optional) -# COMPAT compat entry point (optional) - -set -e - -usage() { - echo >&2 "usage: $0 [--abis ABIS] INFILE OUTFILE" >&2 - echo >&2 - echo >&2 " INFILE input syscall table" - echo >&2 " OUTFILE output header file" - echo >&2 - echo >&2 "options:" - echo >&2 " --abis ABIS ABI(s) to handle (By default, all lines are handled)" - exit 1 -} - -# default unless specified by options -abis= - -while [ $# -gt 0 ] -do - case $1 in - --abis) - abis=$(echo "($2)" | tr ',' '|') - shift 2;; - -*) - echo "$1: unknown option" >&2 - usage;; - *) - break;; - esac -done - -if [ $# -ne 2 ]; then - usage -fi - -infile="$1" -outfile="$2" - -sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX) -grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table - -echo "static const char *const syscall_num_to_name[] = {" > $outfile -# the params are: nr abi name entry compat -# use _ for intentionally unused variables according to SC2034 -while read nr _ name _ _; do - echo " [$nr] = \"$name\"," >> $outfile -done < $sorted_table -echo "};" >> $outfile - -echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile - -# When sorting by name, add a suffix of 0s upto 20 characters so that system -# calls that differ with a numerical suffix don't sort before those -# without. This default behavior of sort differs from that of strcmp used at -# runtime. Use sed to strip the trailing 0s suffix afterwards. -grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > $sorted_table -while read name nr; do - echo " $nr, /* $name */" >> $outfile -done < $sorted_table -echo "};" >> $outfile - -rm -f $sorted_table -- cgit v1.2.3 From 168910d0f9377b23b98404c88c13d4c51cdc5f15 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 11 Mar 2025 14:36:25 -0700 Subject: perf build: Add mypy build tests If MYPY=1 is passed to the build then run mypy over python code in perf. Unlike shellcheck this isn't default on as there are currently too many errors. An example of an error: ``` util/setup.py:8: error: Item "None" of "str | None" has no attribute "split" [union-attr] util/setup.py:15: error: Item "None" of "IO[bytes] | None" has no attribute "readline" [union-attr] util/setup.py:15: error: List item 0 has incompatible type "str | None"; expected "str | bytes | PathLike[str] | PathLike[bytes]" [list-item] util/setup.py:16: error: Unsupported left operand type for + ("None") [operator] util/setup.py:16: note: Left operand is of type "str | None" util/setup.py:74: error: Unsupported left operand type for + ("None") [operator] util/setup.py:74: note: Left operand is of type "str | None" Found 5 errors in 1 file (checked 1 source file) make[4]: *** [util/Build:430: util/setup.py.mypy_log] Error 1 ``` Reviewed-by: James Clark Signed-off-by: Ian Rogers Link: https://lore.kernel.org/r/20250311213628.569562-4-irogers@google.com Signed-off-by: Namhyung Kim --- tools/perf/scripts/Build | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tools/perf/scripts') diff --git a/tools/perf/scripts/Build b/tools/perf/scripts/Build index 46f0c6f76dbf..a5350dc6ac50 100644 --- a/tools/perf/scripts/Build +++ b/tools/perf/scripts/Build @@ -2,3 +2,16 @@ ifeq ($(CONFIG_LIBTRACEEVENT),y) perf-util-$(CONFIG_LIBPERL) += perl/Perf-Trace-Util/ endif perf-util-$(CONFIG_LIBPYTHON) += python/Perf-Trace-Util/ + +ifdef MYPY + PY_TESTS := $(shell find python -type f -name '*.py') + MYPY_TEST_LOGS := $(PY_TESTS:python/%=python/%.mypy_log) +else + MYPY_TEST_LOGS := +endif + +$(OUTPUT)%.mypy_log: % + $(call rule_mkdir) + $(Q)$(call echo-cmd,test)mypy "$<" > $@ || (cat $@ && rm $@ && false) + +perf-y += $(MYPY_TEST_LOGS) -- cgit v1.2.3 From 8a54784e708b51c1dcead1471bbee5fb31ae92cc Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 11 Mar 2025 14:36:26 -0700 Subject: perf build: Add pylint build tests If PYLINT=1 is passed to the build then run pylint over python code in perf. Unlike shellcheck this isn't default on as there are currently too many errors. An example of an error: ``` ************* Module setup util/setup.py:19:0: C0301: Line too long (127/100) (line-too-long) util/setup.py:20:0: C0301: Line too long (138/100) (line-too-long) util/setup.py:63:0: C0301: Line too long (106/100) (line-too-long) util/setup.py:1:0: C0114: Missing module docstring (missing-module-docstring) util/setup.py:24:4: W0622: Redefining built-in 'vars' (redefined-builtin) util/setup.py:11:4: C0103: Constant name "cc_options" doesn't conform to UPPER_CASE naming style (invalid-name) util/setup.py:13:4: C0103: Constant name "cc_options" doesn't conform to UPPER_CASE naming style (invalid-name) util/setup.py:15:34: R1732: Consider using 'with' for resource-allocating operations (consider-using-with) util/setup.py:18:0: C0116: Missing function or method docstring (missing-function-docstring) util/setup.py:19:16: R1732: Consider using 'with' for resource-allocating operations (consider-using-with) util/setup.py:44:0: C0413: Import "from setuptools import setup, Extension" should be placed at the top of the module (wrong-import-position) util/setup.py:46:0: C0413: Import "from setuptools.command.build_ext import build_ext as _build_ext" should be placed at the top of the module (wrong-import-position) util/setup.py:47:0: C0413: Import "from setuptools.command.install_lib import install_lib as _install_lib" should be placed at the top of the module (wrong-import-position) util/setup.py:49:0: C0115: Missing class docstring (missing-class-docstring) util/setup.py:49:0: C0103: Class name "build_ext" doesn't conform to PascalCase naming style (invalid-name) util/setup.py:52:8: W0201: Attribute 'build_lib' defined outside __init__ (attribute-defined-outside-init) util/setup.py:53:8: W0201: Attribute 'build_temp' defined outside __init__ (attribute-defined-outside-init) util/setup.py:55:0: C0115: Missing class docstring (missing-class-docstring) util/setup.py:55:0: C0103: Class name "install_lib" doesn't conform to PascalCase naming style (invalid-name) util/setup.py:58:8: W0201: Attribute 'build_dir' defined outside __init__ (attribute-defined-outside-init) *----------------------------------------------------------------- Your code has been rated at 6.67/10 (previous run: 6.51/10, +0.16) make[4]: *** [util/Build:442: util/setup.py.pylint_log] Error 1 ``` Reviewed-by: James Clark Signed-off-by: Ian Rogers Link: https://lore.kernel.org/r/20250311213628.569562-5-irogers@google.com Signed-off-by: Namhyung Kim --- tools/perf/scripts/Build | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tools/perf/scripts') diff --git a/tools/perf/scripts/Build b/tools/perf/scripts/Build index a5350dc6ac50..91229a1fe3ff 100644 --- a/tools/perf/scripts/Build +++ b/tools/perf/scripts/Build @@ -15,3 +15,16 @@ $(OUTPUT)%.mypy_log: % $(Q)$(call echo-cmd,test)mypy "$<" > $@ || (cat $@ && rm $@ && false) perf-y += $(MYPY_TEST_LOGS) + +ifdef PYLINT + PY_TESTS := $(shell find python -type f -name '*.py') + PYLINT_TEST_LOGS := $(PY_TESTS:python/%=python/%.pylint_log) +else + PYLINT_TEST_LOGS := +endif + +$(OUTPUT)%.pylint_log: % + $(call rule_mkdir) + $(Q)$(call echo-cmd,test)pylint "$<" > $@ || (cat $@ && rm $@ && false) + +perf-y += $(PYLINT_TEST_LOGS) -- cgit v1.2.3