]> www.infradead.org Git - users/hch/misc.git/commitdiff
perf test: Extend branch stack sampling test for Arm64 BRBE
authorJames Clark <james.clark@linaro.org>
Wed, 13 Aug 2025 13:38:51 +0000 (14:38 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 1 Oct 2025 18:31:49 +0000 (15:31 -0300)
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>
tools/perf/tests/builtin-test.c
tools/perf/tests/shell/test_brstack.sh
tools/perf/tests/tests.h
tools/perf/tests/workloads/Build
tools/perf/tests/workloads/traploop.c [new file with mode: 0644]

index 85142dfb3e01c24593e6c7e168398d7ebfe91d3e..8921846b3f369fbd45c9f3378e783638222ccff1 100644 (file)
@@ -152,6 +152,7 @@ static struct test_workload *workloads[] = {
        &workload__brstack,
        &workload__datasym,
        &workload__landlock,
+       &workload__traploop,
 };
 
 #define workloads__for_each(workload) \
index 252d22d39c7b0ac2eea25583abba10032697f761..85233d435be63eec561863e3325c7e228e74b8d4 100755 (executable)
@@ -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"
index 97e62db8764a053720841896f5b735459c76a896..cf3a14a95b6749a6a98a9c720c4ae67cd56668eb 100644 (file)
@@ -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;
index 5af17206f04d16fde707547538cffcda52941cab..fb1012cc4fc31e2be2950667144c45cb6f247870 100644 (file)
@@ -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 (file)
index 0000000..68dec39
--- /dev/null
@@ -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);