1#!/bin/bash 2# perf record LBR tests (exclusive) 3# SPDX-License-Identifier: GPL-2.0 4 5set -e 6 7if [ ! -f /sys/devices/cpu/caps/branches ] && [ ! -f /sys/devices/cpu_core/caps/branches ] 8then 9 echo "Skip: only x86 CPUs support LBR" 10 exit 2 11fi 12 13err=0 14perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 15 16cleanup() { 17 rm -rf "${perfdata}" 18 rm -rf "${perfdata}".old 19 rm -rf "${perfdata}".txt 20 21 trap - EXIT TERM INT 22} 23 24trap_cleanup() { 25 cleanup 26 exit 1 27} 28trap trap_cleanup EXIT TERM INT 29 30 31lbr_callgraph_test() { 32 test="LBR callgraph" 33 34 echo "$test" 35 if ! perf record -e cycles --call-graph lbr -o "${perfdata}" perf test -w thloop 36 then 37 echo "$test [Failed support missing]" 38 if [ $err -eq 0 ] 39 then 40 err=2 41 fi 42 return 43 fi 44 45 if ! perf report --stitch-lbr -i "${perfdata}" > "${perfdata}".txt 46 then 47 cat "${perfdata}".txt 48 echo "$test [Failed in perf report]" 49 err=1 50 return 51 fi 52 53 echo "$test [Success]" 54} 55 56lbr_test() { 57 local branch_flags=$1 58 local test="LBR $2 test" 59 local threshold=$3 60 local out 61 local sam_nr 62 local bs_nr 63 local zero_nr 64 local r 65 66 echo "$test" 67 if ! perf record -e cycles $branch_flags -o "${perfdata}" perf test -w thloop 68 then 69 echo "$test [Failed support missing]" 70 perf record -e cycles $branch_flags -o "${perfdata}" perf test -w thloop || true 71 if [ $err -eq 0 ] 72 then 73 err=2 74 fi 75 return 76 fi 77 78 out=$(perf report -D -i "${perfdata}" 2> /dev/null | grep -A1 'PERF_RECORD_SAMPLE') 79 sam_nr=$(echo "$out" | grep -c 'PERF_RECORD_SAMPLE' || true) 80 if [ $sam_nr -eq 0 ] 81 then 82 echo "$test [Failed no samples captured]" 83 err=1 84 return 85 fi 86 echo "$test: $sam_nr samples" 87 88 bs_nr=$(echo "$out" | grep -c 'branch stack: nr:' || true) 89 if [ $sam_nr -ne $bs_nr ] 90 then 91 echo "$test [Failed samples missing branch stacks]" 92 err=1 93 return 94 fi 95 96 zero_nr=$(echo "$out" | grep -c 'branch stack: nr:0' || true) 97 r=$(($zero_nr * 100 / $bs_nr)) 98 if [ $r -gt $threshold ]; then 99 echo "$test [Failed empty br stack ratio exceed $threshold%: $r%]" 100 err=1 101 return 102 fi 103 104 echo "$test [Success]" 105} 106 107parallel_lbr_test() { 108 err=0 109 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 110 lbr_test "$1" "$2" "$3" 111 cleanup 112 exit $err 113} 114 115lbr_callgraph_test 116 117# Sequential 118lbr_test "-b" "any branch" 2 119lbr_test "-j any_call" "any call" 2 120lbr_test "-j any_ret" "any ret" 2 121lbr_test "-j ind_call" "any indirect call" 2 122lbr_test "-j ind_jmp" "any indirect jump" 100 123lbr_test "-j call" "direct calls" 2 124lbr_test "-j ind_call,u" "any indirect user call" 100 125lbr_test "-a -b" "system wide any branch" 2 126lbr_test "-a -j any_call" "system wide any call" 2 127 128# Parallel 129parallel_lbr_test "-b" "parallel any branch" 100 & 130pid1=$! 131parallel_lbr_test "-j any_call" "parallel any call" 100 & 132pid2=$! 133parallel_lbr_test "-j any_ret" "parallel any ret" 100 & 134pid3=$! 135parallel_lbr_test "-j ind_call" "parallel any indirect call" 100 & 136pid4=$! 137parallel_lbr_test "-j ind_jmp" "parallel any indirect jump" 100 & 138pid5=$! 139parallel_lbr_test "-j call" "parallel direct calls" 100 & 140pid6=$! 141parallel_lbr_test "-j ind_call,u" "parallel any indirect user call" 100 & 142pid7=$! 143parallel_lbr_test "-a -b" "parallel system wide any branch" 100 & 144pid8=$! 145parallel_lbr_test "-a -j any_call" "parallel system wide any call" 100 & 146pid9=$! 147 148for pid in $pid1 $pid2 $pid3 $pid4 $pid5 $pid6 $pid7 $pid8 $pid9 149do 150 set +e 151 wait $pid 152 child_err=$? 153 set -e 154 if ([ $err -eq 2 ] && [ $child_err -eq 1 ]) || [ $err -eq 0 ] 155 then 156 err=$child_err 157 fi 158done 159 160cleanup 161exit $err 162