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>
This commit is contained in:
James Clark 2025-08-13 14:38:51 +01:00 committed by Arnaldo Carvalho de Melo
parent 11e59335b0
commit 9f0fa21379
5 changed files with 60 additions and 1 deletions

View File

@ -152,6 +152,7 @@ static struct test_workload *workloads[] = {
&workload__brstack,
&workload__datasym,
&workload__landlock,
&workload__traploop,
};
#define workloads__for_each(workload) \

View File

@ -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"

View 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;

View 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

View File

@ -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);