[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250813-james-brbe-test-v1-3-76a0144b73fb@linaro.org>
Date: Wed, 13 Aug 2025 14:38:51 +0100
From: James Clark <james.clark@...aro.org>
To: Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...hat.com>,
Arnaldo Carvalho de Melo <acme@...nel.org>,
Namhyung Kim <namhyung@...nel.org>, Mark Rutland <mark.rutland@....com>,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
Jiri Olsa <jolsa@...nel.org>, Ian Rogers <irogers@...gle.com>,
Adrian Hunter <adrian.hunter@...el.com>,
Anshuman Khandual <anshuman.khandual@....com>,
Mark Rutland <mark.rutland@....com>, "Rob Herring (Arm)" <robh@...nel.org>,
Adam Young <admiyo@...amperecomputing.com>, Will Deacon <will@...nel.org>,
German Gomez <german.gomez@....com>
Cc: linux-perf-users@...r.kernel.org, linux-kernel@...r.kernel.org,
James Clark <james.clark@...aro.org>
Subject: [PATCH 3/3] 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.
Co-developed-by: German Gomez <german.gomez@....com>
Signed-off-by: German Gomez <german.gomez@....com>
Signed-off-by: James Clark <james.clark@...aro.org>
---
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/shell/test_brstack.sh | 26 +++++++++++++++++++++++++-
tools/perf/tests/tests.h | 1 +
tools/perf/tests/workloads/Build | 2 ++
tools/perf/tests/workloads/traploop.c | 31 +++++++++++++++++++++++++++++++
5 files changed, 60 insertions(+), 1 deletion(-)
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);
--
2.34.1
Powered by blists - more mailing lists