linux/tools/perf/tests/shell/test_brstack.sh
Athira Rajeev f4a2aade68 perf tests powerpc: Fix branch stack sampling test to include sanity check for branch filter
Commit b55878c90a ("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>
2022-09-26 10:24:31 -03:00

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"