1b55878c9SGerman Gomez#!/bin/sh
2b55878c9SGerman Gomez# Check branch stack sampling
3b55878c9SGerman Gomez
4b55878c9SGerman Gomez# SPDX-License-Identifier: GPL-2.0
5b55878c9SGerman Gomez# German Gomez <[email protected]>, 2022
6b55878c9SGerman Gomez
7fcfb5a61SAdrian Huntershelldir=$(dirname "$0")
8fcfb5a61SAdrian Hunter# shellcheck source=lib/perf_has_symbol.sh
9fcfb5a61SAdrian Hunter. "${shelldir}"/lib/perf_has_symbol.sh
10fcfb5a61SAdrian Hunter
11b55878c9SGerman Gomez# skip the test if the hardware doesn't support branch stack sampling
12f4a2aadeSAthira Rajeev# and if the architecture doesn't support filter types: any,save_type,u
1320ebc4a6SJames Clarkif ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev/null 2>&1 ; then
1420ebc4a6SJames Clark	echo "skip: system doesn't support filter types: any,save_type,u"
1520ebc4a6SJames Clark	exit 2
1620ebc4a6SJames Clarkfi
17b55878c9SGerman Gomez
18fcfb5a61SAdrian Hunterskip_test_missing_symbol brstack_bench
19fcfb5a61SAdrian Hunter
20b55878c9SGerman GomezTMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX)
217bc1dd96SNamhyung KimTESTPROG="perf test -w brstack"
22b55878c9SGerman Gomez
23b55878c9SGerman Gomezcleanup() {
24b55878c9SGerman Gomez	rm -rf $TMPDIR
25b55878c9SGerman Gomez}
26b55878c9SGerman Gomez
273b3bf0d1SGeetikatrap cleanup EXIT TERM INT
28b55878c9SGerman Gomez
29b55878c9SGerman Gomeztest_user_branches() {
30b55878c9SGerman Gomez	echo "Testing user branch stack sampling"
31b55878c9SGerman Gomez
327bc1dd96SNamhyung Kim	perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- ${TESTPROG} > /dev/null 2>&1
33*3178155dSJames Clark	perf script -i $TMPDIR/perf.data --fields brstacksym | tr -s ' ' '\n' > $TMPDIR/perf.script
34b55878c9SGerman Gomez
35b55878c9SGerman Gomez	# example of branch entries:
367bc1dd96SNamhyung Kim	# 	brstack_foo+0x14/brstack_bar+0x40/P/-/-/0/CALL
37b55878c9SGerman Gomez
38b55878c9SGerman Gomez	set -x
398eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/IND_CALL/.*$"	$TMPDIR/perf.script
408eaf8ec3SSandipan Das	grep -E -m1 "^brstack_foo\+[^ ]*/brstack_bar\+[^ ]*/CALL/.*$"	$TMPDIR/perf.script
418eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/CALL/.*$"	$TMPDIR/perf.script
428eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_bar\+[^ ]*/CALL/.*$"	$TMPDIR/perf.script
438eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bar\+[^ ]*/brstack_foo\+[^ ]*/RET/.*$"		$TMPDIR/perf.script
448eaf8ec3SSandipan Das	grep -E -m1 "^brstack_foo\+[^ ]*/brstack_bench\+[^ ]*/RET/.*$"	$TMPDIR/perf.script
458eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_bench\+[^ ]*/COND/.*$"	$TMPDIR/perf.script
468eaf8ec3SSandipan Das	grep -E -m1 "^brstack\+[^ ]*/brstack\+[^ ]*/UNCOND/.*$"		$TMPDIR/perf.script
47b55878c9SGerman Gomez	set +x
48b55878c9SGerman Gomez
49b55878c9SGerman Gomez	# some branch types are still not being tested:
50b55878c9SGerman Gomez	# IND COND_CALL COND_RET SYSCALL SYSRET IRQ SERROR NO_TX
51b55878c9SGerman Gomez}
52b55878c9SGerman Gomez
53b55878c9SGerman Gomez# first argument <arg0> is the argument passed to "--branch-stack <arg0>,save_type,u"
54b55878c9SGerman Gomez# second argument are the expected branch types for the given filter
55b55878c9SGerman Gomeztest_filter() {
563b3bf0d1SGeetika	test_filter_filter=$1
573b3bf0d1SGeetika	test_filter_expect=$2
58b55878c9SGerman Gomez
593b3bf0d1SGeetika	echo "Testing branch stack filtering permutation ($test_filter_filter,$test_filter_expect)"
60b55878c9SGerman Gomez
613b3bf0d1SGeetika	perf record -o $TMPDIR/perf.data --branch-filter $test_filter_filter,save_type,u -- ${TESTPROG} > /dev/null 2>&1
62*3178155dSJames Clark	perf script -i $TMPDIR/perf.data --fields brstack | tr -s ' ' '\n' | grep '.' > $TMPDIR/perf.script
63b55878c9SGerman Gomez
64b55878c9SGerman Gomez	# fail if we find any branch type that doesn't match any of the expected ones
65b55878c9SGerman Gomez	# also consider UNKNOWN branch types (-)
663b3bf0d1SGeetika	if grep -E -vm1 "^[^ ]*/($test_filter_expect|-|( *))/.*$" $TMPDIR/perf.script; then
67b55878c9SGerman Gomez		return 1
68b55878c9SGerman Gomez	fi
69b55878c9SGerman Gomez}
70b55878c9SGerman Gomez
71b55878c9SGerman Gomezset -e
72b55878c9SGerman Gomez
73b55878c9SGerman Gomeztest_user_branches
74b55878c9SGerman Gomez
75b55878c9SGerman Gomeztest_filter "any_call"	"CALL|IND_CALL|COND_CALL|SYSCALL|IRQ"
76b55878c9SGerman Gomeztest_filter "call"	"CALL|SYSCALL"
77b55878c9SGerman Gomeztest_filter "cond"	"COND"
78b55878c9SGerman Gomeztest_filter "any_ret"	"RET|COND_RET|SYSRET|ERET"
79b55878c9SGerman Gomez
80b55878c9SGerman Gomeztest_filter "call,cond"		"CALL|SYSCALL|COND"
81b55878c9SGerman Gomeztest_filter "any_call,cond"		"CALL|IND_CALL|COND_CALL|IRQ|SYSCALL|COND"
82b55878c9SGerman Gomeztest_filter "cond,any_call,any_ret"	"COND|CALL|IND_CALL|COND_CALL|SYSCALL|IRQ|RET|COND_RET|SYSRET|ERET"
83