1b55878c9SGerman Gomez#!/bin/sh
2b55878c9SGerman Gomez# Check branch stack sampling
3b55878c9SGerman Gomez
4b55878c9SGerman Gomez# SPDX-License-Identifier: GPL-2.0
5b55878c9SGerman Gomez# German Gomez <german.gomez@arm.com>, 2022
6b55878c9SGerman Gomez
7b55878c9SGerman Gomez# skip the test if the hardware doesn't support branch stack sampling
8f4a2aadeSAthira Rajeev# and if the architecture doesn't support filter types: any,save_type,u
920ebc4a6SJames Clarkif ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev/null 2>&1 ; then
1020ebc4a6SJames Clark	echo "skip: system doesn't support filter types: any,save_type,u"
1120ebc4a6SJames Clark	exit 2
1220ebc4a6SJames Clarkfi
13b55878c9SGerman Gomez
14b55878c9SGerman GomezTMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX)
157bc1dd96SNamhyung KimTESTPROG="perf test -w brstack"
16b55878c9SGerman Gomez
17b55878c9SGerman Gomezcleanup() {
18b55878c9SGerman Gomez	rm -rf $TMPDIR
19b55878c9SGerman Gomez}
20b55878c9SGerman Gomez
21*3b3bf0d1SGeetikatrap cleanup EXIT TERM INT
22b55878c9SGerman Gomez
23b55878c9SGerman Gomeztest_user_branches() {
24b55878c9SGerman Gomez	echo "Testing user branch stack sampling"
25b55878c9SGerman Gomez
267bc1dd96SNamhyung Kim	perf record -o $TMPDIR/perf.data --branch-filter any,save_type,u -- ${TESTPROG} > /dev/null 2>&1
27b55878c9SGerman Gomez	perf script -i $TMPDIR/perf.data --fields brstacksym | xargs -n1 > $TMPDIR/perf.script
28b55878c9SGerman Gomez
29b55878c9SGerman Gomez	# example of branch entries:
307bc1dd96SNamhyung Kim	# 	brstack_foo+0x14/brstack_bar+0x40/P/-/-/0/CALL
31b55878c9SGerman Gomez
32b55878c9SGerman Gomez	set -x
338eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/IND_CALL/.*$"	$TMPDIR/perf.script
348eaf8ec3SSandipan Das	grep -E -m1 "^brstack_foo\+[^ ]*/brstack_bar\+[^ ]*/CALL/.*$"	$TMPDIR/perf.script
358eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_foo\+[^ ]*/CALL/.*$"	$TMPDIR/perf.script
368eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_bar\+[^ ]*/CALL/.*$"	$TMPDIR/perf.script
378eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bar\+[^ ]*/brstack_foo\+[^ ]*/RET/.*$"		$TMPDIR/perf.script
388eaf8ec3SSandipan Das	grep -E -m1 "^brstack_foo\+[^ ]*/brstack_bench\+[^ ]*/RET/.*$"	$TMPDIR/perf.script
398eaf8ec3SSandipan Das	grep -E -m1 "^brstack_bench\+[^ ]*/brstack_bench\+[^ ]*/COND/.*$"	$TMPDIR/perf.script
408eaf8ec3SSandipan Das	grep -E -m1 "^brstack\+[^ ]*/brstack\+[^ ]*/UNCOND/.*$"		$TMPDIR/perf.script
41b55878c9SGerman Gomez	set +x
42b55878c9SGerman Gomez
43b55878c9SGerman Gomez	# some branch types are still not being tested:
44b55878c9SGerman Gomez	# IND COND_CALL COND_RET SYSCALL SYSRET IRQ SERROR NO_TX
45b55878c9SGerman Gomez}
46b55878c9SGerman Gomez
47b55878c9SGerman Gomez# first argument <arg0> is the argument passed to "--branch-stack <arg0>,save_type,u"
48b55878c9SGerman Gomez# second argument are the expected branch types for the given filter
49b55878c9SGerman Gomeztest_filter() {
50*3b3bf0d1SGeetika	test_filter_filter=$1
51*3b3bf0d1SGeetika	test_filter_expect=$2
52b55878c9SGerman Gomez
53*3b3bf0d1SGeetika	echo "Testing branch stack filtering permutation ($test_filter_filter,$test_filter_expect)"
54b55878c9SGerman Gomez
55*3b3bf0d1SGeetika	perf record -o $TMPDIR/perf.data --branch-filter $test_filter_filter,save_type,u -- ${TESTPROG} > /dev/null 2>&1
56b55878c9SGerman Gomez	perf script -i $TMPDIR/perf.data --fields brstack | xargs -n1 > $TMPDIR/perf.script
57b55878c9SGerman Gomez
58b55878c9SGerman Gomez	# fail if we find any branch type that doesn't match any of the expected ones
59b55878c9SGerman Gomez	# also consider UNKNOWN branch types (-)
60*3b3bf0d1SGeetika	if grep -E -vm1 "^[^ ]*/($test_filter_expect|-|( *))/.*$" $TMPDIR/perf.script; then
61b55878c9SGerman Gomez		return 1
62b55878c9SGerman Gomez	fi
63b55878c9SGerman Gomez}
64b55878c9SGerman Gomez
65b55878c9SGerman Gomezset -e
66b55878c9SGerman Gomez
67b55878c9SGerman Gomeztest_user_branches
68b55878c9SGerman Gomez
69b55878c9SGerman Gomeztest_filter "any_call"	"CALL|IND_CALL|COND_CALL|SYSCALL|IRQ"
70b55878c9SGerman Gomeztest_filter "call"	"CALL|SYSCALL"
71b55878c9SGerman Gomeztest_filter "cond"	"COND"
72b55878c9SGerman Gomeztest_filter "any_ret"	"RET|COND_RET|SYSRET|ERET"
73b55878c9SGerman Gomez
74b55878c9SGerman Gomeztest_filter "call,cond"		"CALL|SYSCALL|COND"
75b55878c9SGerman Gomeztest_filter "any_call,cond"		"CALL|IND_CALL|COND_CALL|IRQ|SYSCALL|COND"
76b55878c9SGerman Gomeztest_filter "cond,any_call,any_ret"	"COND|CALL|IND_CALL|COND_CALL|SYSCALL|IRQ|RET|COND_RET|SYSRET|ERET"
77