diff options
author | James Clark <james.clark@linaro.org> | 2025-08-13 14:38:51 +0100 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2025-10-01 15:31:49 -0300 |
commit | 9f0fa213790e3633d37e981386da99149573135b (patch) | |
tree | 7731bde94ae25719c245a3e6423661b6e17ebeea | |
parent | 11e59335b0d1c4bc259ee6f0533e04c4b3a9f1dd (diff) |
perf test: Extend branch stack sampling test for Arm64 BRBE
BRBE emits IRQ and ERET branches for branching and returning from
trapped instructions. Add a test that loops on a trapped instruction
(MRS - Read special register) for this.
Extend the expected 'any_call' branches to include FAULT_DATA and
FAULT_INST as these are emitted by BRBE.
Reviewed-by: Ian Rogers <irogers@google.com>
Co-developed-by: German Gomez <german.gomez@arm.com>
Signed-off-by: German Gomez <german.gomez@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
Cc: Adam Young <admiyo@os.amperecomputing.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/tests/builtin-test.c | 1 | ||||
-rwxr-xr-x | tools/perf/tests/shell/test_brstack.sh | 26 | ||||
-rw-r--r-- | tools/perf/tests/tests.h | 1 | ||||
-rw-r--r-- | tools/perf/tests/workloads/Build | 2 | ||||
-rw-r--r-- | tools/perf/tests/workloads/traploop.c | 31 |
5 files changed, 60 insertions, 1 deletions
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 85142dfb3e01..8921846b3f36 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -152,6 +152,7 @@ static struct test_workload *workloads[] = { &workload__brstack, &workload__datasym, &workload__landlock, + &workload__traploop, }; #define workloads__for_each(workload) \ diff --git a/tools/perf/tests/shell/test_brstack.sh b/tools/perf/tests/shell/test_brstack.sh index 252d22d39c7b..85233d435be6 100755 --- a/tools/perf/tests/shell/test_brstack.sh +++ b/tools/perf/tests/shell/test_brstack.sh @@ -34,6 +34,10 @@ trap_cleanup() { } trap trap_cleanup EXIT TERM INT +is_arm64() { + [ "$(uname -m)" = "aarch64" ]; +} + check_branches() { if ! tr -s ' ' '\n' < "$TMPDIR/perf.script" | grep -E -m1 -q "$1"; then echo "Branches missing $1" @@ -76,9 +80,24 @@ test_user_branches() { err=1 fi # some branch types are still not being tested: - # IND COND_CALL COND_RET SYSRET IRQ SERROR NO_TX + # IND COND_CALL COND_RET SYSRET SERROR NO_TX } +test_trap_eret_branches() { + echo "Testing trap & eret branches" + if ! is_arm64; then + echo "skip: not arm64" + else + perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u,k -- \ + perf test -w traploop 1000 + perf script -i $TMPDIR/perf.data --fields brstacksym | \ + tr ' ' '\n' > $TMPDIR/perf.script + + # BRBINF<n>.TYPE == TRAP are mapped to PERF_BR_IRQ by the BRBE driver + check_branches "^trap_bench\+[^ ]+/[^ ]/IRQ/" + check_branches "^[^ ]+/trap_bench\+[^ ]+/ERET/" + fi +} test_kernel_branches() { echo "Testing that k option only includes kernel source addresses" @@ -162,9 +181,14 @@ set -e test_user_branches test_syscall test_kernel_branches +test_trap_eret_branches any_call="CALL|IND_CALL|COND_CALL|SYSCALL|IRQ" +if is_arm64; then + any_call="$any_call|FAULT_DATA|FAULT_INST" +fi + test_filter "any_call" "$any_call" test_filter "call" "CALL|SYSCALL" test_filter "cond" "COND" diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 97e62db8764a..cf3a14a95b67 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -239,6 +239,7 @@ DECLARE_WORKLOAD(sqrtloop); DECLARE_WORKLOAD(brstack); DECLARE_WORKLOAD(datasym); DECLARE_WORKLOAD(landlock); +DECLARE_WORKLOAD(traploop); extern const char *dso_to_test; extern const char *test_objdump_path; diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index 5af17206f04d..fb1012cc4fc3 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -7,8 +7,10 @@ perf-test-y += sqrtloop.o perf-test-y += brstack.o perf-test-y += datasym.o perf-test-y += landlock.o +perf-test-y += traploop.o CFLAGS_sqrtloop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer -U_FORTIFY_SOURCE CFLAGS_brstack.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_datasym.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE +CFLAGS_traploop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE diff --git a/tools/perf/tests/workloads/traploop.c b/tools/perf/tests/workloads/traploop.c new file mode 100644 index 000000000000..68dec399a735 --- /dev/null +++ b/tools/perf/tests/workloads/traploop.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <stdlib.h> +#include "../tests.h" + +#define BENCH_RUNS 999999 + +#ifdef __aarch64__ +static void trap_bench(void) +{ + unsigned long val; + + asm("mrs %0, ID_AA64ISAR0_EL1" : "=r" (val)); /* TRAP + ERET */ +} +#else +static void trap_bench(void) { } +#endif + +static int traploop(int argc, const char **argv) +{ + int num_loops = BENCH_RUNS; + + if (argc > 0) + num_loops = atoi(argv[0]); + + for (int i = 0; i < num_loops; i++) + trap_bench(); + + return 0; +} + +DEFINE_WORKLOAD(traploop); |