mirror of
https://github.com/torvalds/linux.git
synced 2024-11-30 16:11:38 +00:00
f4a2aade68
Commitb55878c90a
("perf test: Add test for branch stack sampling") added test for branch stack sampling. There is a sanity check in the beginning to skip the test if the hardware doesn't support branch stack sampling. Snippet <<>> skip the test if the hardware doesn't support branch stack sampling perf record -b -o- -B true > /dev/null 2>&1 || exit 2 <<>> But the testcase also uses branch sample types: save_type, any. if any platform doesn't support the branch filters used in the test, the testcase will fail. In powerpc, currently mutliple branch filters are not supported and hence this test fails in powerpc. Fix the sanity check to look at the support for branch filters used in this test before proceeding with the test. Fixes:b55878c90a
("perf test: Add test for branch stack sampling") Reported-by: Disha Goel <disgoel@linux.vnet.ibm.com> Reviewed-by: Kajol Jain <kjain@linux.ibm.com> Signed-off-by: Athira Jajeev <atrajeev@linux.vnet.ibm.com> Cc: German Gomez <german.gomez@arm.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: linuxppc-dev@lists.ozlabs.org Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nageswara R Sastry <rnsastry@linux.ibm.com> Link: https://lore.kernel.org/r/20220921145255.20972-2-atrajeev@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
116 lines
3.3 KiB
Bash
Executable File
116 lines
3.3 KiB
Bash
Executable File
#!/bin/sh
|
|
# Check branch stack sampling
|
|
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# German Gomez <german.gomez@arm.com>, 2022
|
|
|
|
# we need a C compiler to build the test programs
|
|
# so bail if none is found
|
|
if ! [ -x "$(command -v cc)" ]; then
|
|
echo "failed: no compiler, install gcc"
|
|
exit 2
|
|
fi
|
|
|
|
# skip the test if the hardware doesn't support branch stack sampling
|
|
# and if the architecture doesn't support filter types: any,save_type,u
|
|
perf record -b -o- -B --branch-filter any,save_type,u true > /dev/null 2>&1 || exit 2
|
|
|
|
TMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX)
|
|
|
|
cleanup() {
|
|
rm -rf $TMPDIR
|
|
}
|
|
|
|
trap cleanup exit term int
|
|
|
|
gen_test_program() {
|
|
# generate test program
|
|
cat << EOF > $1
|
|
#define BENCH_RUNS 999999
|
|
int cnt;
|
|
void bar(void) {
|
|
} /* return */
|
|
void foo(void) {
|
|
bar(); /* call */
|
|
} /* return */
|
|
void bench(void) {
|
|
void (*foo_ind)(void) = foo;
|
|
if ((cnt++) % 3) /* branch (cond) */
|
|
foo(); /* call */
|
|
bar(); /* call */
|
|
foo_ind(); /* call (ind) */
|
|
}
|
|
int main(void)
|
|
{
|
|
int cnt = 0;
|
|
while (1) {
|
|
if ((cnt++) > BENCH_RUNS)
|
|
break;
|
|
bench(); /* call */
|
|
} /* branch (uncond) */
|
|
return 0;
|
|
}
|
|
EOF
|
|
}
|
|
|
|
test_user_branches() {
|
|
echo "Testing user branch stack sampling"
|
|
|
|
gen_test_program "$TEMPDIR/program.c"
|
|
cc -fno-inline -g "$TEMPDIR/program.c" -o $TMPDIR/a.out
|
|
|
|
perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- $TMPDIR/a.out > /dev/null 2>&1
|
|
perf script -i $TMPDIR/perf.data --fields brstacksym | xargs -n1 > $TMPDIR/perf.script
|
|
|
|
# example of branch entries:
|
|
# foo+0x14/bar+0x40/P/-/-/0/CALL
|
|
|
|
set -x
|
|
egrep -m1 "^bench\+[^ ]*/foo\+[^ ]*/IND_CALL$" $TMPDIR/perf.script
|
|
egrep -m1 "^foo\+[^ ]*/bar\+[^ ]*/CALL$" $TMPDIR/perf.script
|
|
egrep -m1 "^bench\+[^ ]*/foo\+[^ ]*/CALL$" $TMPDIR/perf.script
|
|
egrep -m1 "^bench\+[^ ]*/bar\+[^ ]*/CALL$" $TMPDIR/perf.script
|
|
egrep -m1 "^bar\+[^ ]*/foo\+[^ ]*/RET$" $TMPDIR/perf.script
|
|
egrep -m1 "^foo\+[^ ]*/bench\+[^ ]*/RET$" $TMPDIR/perf.script
|
|
egrep -m1 "^bench\+[^ ]*/bench\+[^ ]*/COND$" $TMPDIR/perf.script
|
|
egrep -m1 "^main\+[^ ]*/main\+[^ ]*/UNCOND$" $TMPDIR/perf.script
|
|
set +x
|
|
|
|
# some branch types are still not being tested:
|
|
# IND COND_CALL COND_RET SYSCALL SYSRET IRQ SERROR NO_TX
|
|
}
|
|
|
|
# first argument <arg0> is the argument passed to "--branch-stack <arg0>,save_type,u"
|
|
# second argument are the expected branch types for the given filter
|
|
test_filter() {
|
|
local filter=$1
|
|
local expect=$2
|
|
|
|
echo "Testing branch stack filtering permutation ($filter,$expect)"
|
|
|
|
gen_test_program "$TEMPDIR/program.c"
|
|
cc -fno-inline -g "$TEMPDIR/program.c" -o $TMPDIR/a.out
|
|
|
|
perf record -o $TMPDIR/perf.data --branch-filter $filter,save_type,u -- $TMPDIR/a.out > /dev/null 2>&1
|
|
perf script -i $TMPDIR/perf.data --fields brstack | xargs -n1 > $TMPDIR/perf.script
|
|
|
|
# fail if we find any branch type that doesn't match any of the expected ones
|
|
# also consider UNKNOWN branch types (-)
|
|
if egrep -vm1 "^[^ ]*/($expect|-|( *))$" $TMPDIR/perf.script; then
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
set -e
|
|
|
|
test_user_branches
|
|
|
|
test_filter "any_call" "CALL|IND_CALL|COND_CALL|SYSCALL|IRQ"
|
|
test_filter "call" "CALL|SYSCALL"
|
|
test_filter "cond" "COND"
|
|
test_filter "any_ret" "RET|COND_RET|SYSRET|ERET"
|
|
|
|
test_filter "call,cond" "CALL|SYSCALL|COND"
|
|
test_filter "any_call,cond" "CALL|IND_CALL|COND_CALL|IRQ|SYSCALL|COND"
|
|
test_filter "cond,any_call,any_ret" "COND|CALL|IND_CALL|COND_CALL|SYSCALL|IRQ|RET|COND_RET|SYSRET|ERET"
|