1#!/bin/bash 2# perf record tests 3# SPDX-License-Identifier: GPL-2.0 4 5set -e 6 7shelldir=$(dirname "$0") 8# shellcheck source=lib/waiting.sh 9. "${shelldir}"/lib/waiting.sh 10 11# shellcheck source=lib/perf_has_symbol.sh 12. "${shelldir}"/lib/perf_has_symbol.sh 13 14testsym="test_loop" 15 16skip_test_missing_symbol ${testsym} 17 18err=0 19perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 20testprog="perf test -w thloop" 21cpu_pmu_dir="/sys/bus/event_source/devices/cpu*" 22br_cntr_file="/caps/branch_counter_nr" 23br_cntr_output="branch stack counters" 24br_cntr_script_output="br_cntr: A" 25 26default_fd_limit=$(ulimit -Sn) 27# With option --threads=cpu the number of open file descriptors should be 28# equal to sum of: nmb_cpus * nmb_events (2+dummy), 29# nmb_threads for perf.data.n (equal to nmb_cpus) and 30# 2*nmb_cpus of pipes = 4*nmb_cpus (each pipe has 2 ends) 31# All together it needs 8*nmb_cpus file descriptors plus some are also used 32# outside of testing, thus raising the limit to 16*nmb_cpus 33min_fd_limit=$(($(getconf _NPROCESSORS_ONLN) * 16)) 34 35cleanup() { 36 rm -rf "${perfdata}" 37 rm -rf "${perfdata}".old 38 39 trap - EXIT TERM INT 40} 41 42trap_cleanup() { 43 cleanup 44 exit 1 45} 46trap trap_cleanup EXIT TERM INT 47 48test_per_thread() { 49 echo "Basic --per-thread mode test" 50 if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null 51 then 52 echo "Per-thread record [Skipped event not supported]" 53 return 54 fi 55 if ! perf record --per-thread -o "${perfdata}" ${testprog} 2> /dev/null 56 then 57 echo "Per-thread record [Failed record]" 58 err=1 59 return 60 fi 61 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 62 then 63 echo "Per-thread record [Failed missing output]" 64 err=1 65 return 66 fi 67 68 # run the test program in background (for 30 seconds) 69 ${testprog} 30 & 70 TESTPID=$! 71 72 rm -f "${perfdata}" 73 74 wait_for_threads ${TESTPID} 2 75 perf record -p "${TESTPID}" --per-thread -o "${perfdata}" sleep 1 2> /dev/null 76 kill ${TESTPID} 77 78 if [ ! -e "${perfdata}" ] 79 then 80 echo "Per-thread record [Failed record -p]" 81 err=1 82 return 83 fi 84 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 85 then 86 echo "Per-thread record [Failed -p missing output]" 87 err=1 88 return 89 fi 90 91 echo "Basic --per-thread mode test [Success]" 92} 93 94test_register_capture() { 95 echo "Register capture test" 96 if ! perf list | grep -q 'br_inst_retired.near_call' 97 then 98 echo "Register capture test [Skipped missing event]" 99 return 100 fi 101 if ! perf record --intr-regs=\? 2>&1 | grep -q 'available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15' 102 then 103 echo "Register capture test [Skipped missing registers]" 104 return 105 fi 106 if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call \ 107 -c 1000 --per-thread ${testprog} 2> /dev/null \ 108 | perf script -F ip,sym,iregs -i - 2> /dev/null \ 109 | grep -q "DI:" 110 then 111 echo "Register capture test [Failed missing output]" 112 err=1 113 return 114 fi 115 echo "Register capture test [Success]" 116} 117 118test_system_wide() { 119 echo "Basic --system-wide mode test" 120 if ! perf record -aB --synth=no -o "${perfdata}" ${testprog} 2> /dev/null 121 then 122 echo "System-wide record [Skipped not supported]" 123 return 124 fi 125 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 126 then 127 echo "System-wide record [Failed missing output]" 128 err=1 129 return 130 fi 131 if ! perf record -aB --synth=no -e cpu-clock,cs --threads=cpu \ 132 -o "${perfdata}" ${testprog} 2> /dev/null 133 then 134 echo "System-wide record [Failed record --threads option]" 135 err=1 136 return 137 fi 138 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 139 then 140 echo "System-wide record [Failed --threads missing output]" 141 err=1 142 return 143 fi 144 echo "Basic --system-wide mode test [Success]" 145} 146 147test_workload() { 148 echo "Basic target workload test" 149 if ! perf record -o "${perfdata}" ${testprog} 2> /dev/null 150 then 151 echo "Workload record [Failed record]" 152 err=1 153 return 154 fi 155 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 156 then 157 echo "Workload record [Failed missing output]" 158 err=1 159 return 160 fi 161 if ! perf record -e cpu-clock,cs --threads=package \ 162 -o "${perfdata}" ${testprog} 2> /dev/null 163 then 164 echo "Workload record [Failed record --threads option]" 165 err=1 166 return 167 fi 168 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 169 then 170 echo "Workload record [Failed --threads missing output]" 171 err=1 172 return 173 fi 174 echo "Basic target workload test [Success]" 175} 176 177test_branch_counter() { 178 echo "Branch counter test" 179 # Check if the branch counter feature is supported 180 for dir in $cpu_pmu_dir 181 do 182 if [ ! -e "$dir$br_cntr_file" ] 183 then 184 echo "branch counter feature not supported on all core PMUs ($dir) [Skipped]" 185 return 186 fi 187 done 188 if ! perf record -o "${perfdata}" -e "{branches:p,instructions}" -j any,counter ${testprog} 2> /dev/null 189 then 190 echo "Branch counter record test [Failed record]" 191 err=1 192 return 193 fi 194 if ! perf report -i "${perfdata}" -D -q | grep -q "$br_cntr_output" 195 then 196 echo "Branch counter report test [Failed missing output]" 197 err=1 198 return 199 fi 200 if ! perf script -i "${perfdata}" -F +brstackinsn,+brcntr | grep -q "$br_cntr_script_output" 201 then 202 echo " Branch counter script test [Failed missing output]" 203 err=1 204 return 205 fi 206 echo "Branch counter test [Success]" 207} 208 209test_cgroup() { 210 echo "Cgroup sampling test" 211 if ! perf record -aB --synth=cgroup --all-cgroups -o "${perfdata}" ${testprog} 2> /dev/null 212 then 213 echo "Cgroup sampling [Skipped not supported]" 214 return 215 fi 216 if ! perf report -i "${perfdata}" -D | grep -q "CGROUP" 217 then 218 echo "Cgroup sampling [Failed missing output]" 219 err=1 220 return 221 fi 222 if ! perf script -i "${perfdata}" -F cgroup | grep -q -v "unknown" 223 then 224 echo "Cgroup sampling [Failed cannot resolve cgroup names]" 225 err=1 226 return 227 fi 228 echo "Cgroup sampling test [Success]" 229} 230 231# raise the limit of file descriptors to minimum 232if [[ $default_fd_limit -lt $min_fd_limit ]]; then 233 ulimit -Sn $min_fd_limit 234fi 235 236test_per_thread 237test_register_capture 238test_system_wide 239test_workload 240test_branch_counter 241test_cgroup 242 243# restore the default value 244ulimit -Sn $default_fd_limit 245 246cleanup 247exit $err 248