Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1#!/bin/bash
  2# perf record tests (exclusive)
  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)
 20script_output=$(mktemp /tmp/__perf_test.perf.data.XXXXX.script)
 21testprog="perf test -w thloop"
 22cpu_pmu_dir="/sys/bus/event_source/devices/cpu*"
 23br_cntr_file="/caps/branch_counter_nr"
 24br_cntr_output="branch stack counters"
 25br_cntr_script_output="br_cntr: A"
 26
 27default_fd_limit=$(ulimit -Sn)
 28# With option --threads=cpu the number of open file descriptors should be
 29# equal to sum of:    nmb_cpus * nmb_events (2+dummy),
 30#                     nmb_threads for perf.data.n (equal to nmb_cpus) and
 31#                     2*nmb_cpus of pipes = 4*nmb_cpus (each pipe has 2 ends)
 32# All together it needs 8*nmb_cpus file descriptors plus some are also used
 33# outside of testing, thus raising the limit to 16*nmb_cpus
 34min_fd_limit=$(($(getconf _NPROCESSORS_ONLN) * 16))
 35
 36cleanup() {
 37  rm -rf "${perfdata}"
 38  rm -rf "${perfdata}".old
 39
 40  trap - EXIT TERM INT
 41}
 42
 43trap_cleanup() {
 44  cleanup
 45  exit 1
 46}
 47trap trap_cleanup EXIT TERM INT
 48
 49test_per_thread() {
 50  echo "Basic --per-thread mode test"
 51  if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null
 52  then
 53    echo "Per-thread record [Skipped event not supported]"
 54    return
 55  fi
 56  if ! perf record --per-thread -o "${perfdata}" ${testprog} 2> /dev/null
 57  then
 58    echo "Per-thread record [Failed record]"
 59    err=1
 60    return
 61  fi
 62  if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
 63  then
 64    echo "Per-thread record [Failed missing output]"
 65    err=1
 66    return
 67  fi
 68
 69  # run the test program in background (for 30 seconds)
 70  ${testprog} 30 &
 71  TESTPID=$!
 72
 73  rm -f "${perfdata}"
 74
 75  wait_for_threads ${TESTPID} 2
 76  perf record -p "${TESTPID}" --per-thread -o "${perfdata}" sleep 1 2> /dev/null
 77  kill ${TESTPID}
 78
 79  if [ ! -e "${perfdata}" ]
 80  then
 81    echo "Per-thread record [Failed record -p]"
 82    err=1
 83    return
 84  fi
 85  if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
 86  then
 87    echo "Per-thread record [Failed -p missing output]"
 88    err=1
 89    return
 90  fi
 91
 92  echo "Basic --per-thread mode test [Success]"
 93}
 94
 95test_register_capture() {
 96  echo "Register capture test"
 97  if ! perf list pmu | grep -q 'br_inst_retired.near_call'
 98  then
 99    echo "Register capture test [Skipped missing event]"
100    return
101  fi
102  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'
103  then
104    echo "Register capture test [Skipped missing registers]"
105    return
106  fi
107  if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call \
108    -c 1000 --per-thread ${testprog} 2> /dev/null \
109    | perf script -F ip,sym,iregs -i - 2> /dev/null \
110    | grep -q "DI:"
111  then
112    echo "Register capture test [Failed missing output]"
113    err=1
114    return
115  fi
116  echo "Register capture test [Success]"
117}
118
119test_system_wide() {
120  echo "Basic --system-wide mode test"
121  if ! perf record -aB --synth=no -o "${perfdata}" ${testprog} 2> /dev/null
122  then
123    echo "System-wide record [Skipped not supported]"
124    return
125  fi
126  if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
127  then
128    echo "System-wide record [Failed missing output]"
129    err=1
130    return
131  fi
132  if ! perf record -aB --synth=no -e cpu-clock,cs --threads=cpu \
133    -o "${perfdata}" ${testprog} 2> /dev/null
134  then
135    echo "System-wide record [Failed record --threads option]"
136    err=1
137    return
138  fi
139  if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
140  then
141    echo "System-wide record [Failed --threads missing output]"
142    err=1
143    return
144  fi
145  echo "Basic --system-wide mode test [Success]"
146}
147
148test_workload() {
149  echo "Basic target workload test"
150  if ! perf record -o "${perfdata}" ${testprog} 2> /dev/null
151  then
152    echo "Workload record [Failed record]"
153    err=1
154    return
155  fi
156  if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
157  then
158    echo "Workload record [Failed missing output]"
159    err=1
160    return
161  fi
162  if ! perf record -e cpu-clock,cs --threads=package \
163    -o "${perfdata}" ${testprog} 2> /dev/null
164  then
165    echo "Workload record [Failed record --threads option]"
166    err=1
167    return
168  fi
169  if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
170  then
171    echo "Workload record [Failed --threads missing output]"
172    err=1
173    return
174  fi
175  echo "Basic target workload test [Success]"
176}
177
178test_branch_counter() {
179  echo "Branch counter test"
180  # Check if the branch counter feature is supported
181  for dir in $cpu_pmu_dir
182  do
183    if [ ! -e "$dir$br_cntr_file" ]
184    then
185      echo "branch counter feature not supported on all core PMUs ($dir) [Skipped]"
186      return
187    fi
188  done
189  if ! perf record -o "${perfdata}" -e "{branches:p,instructions}" -j any,counter ${testprog} 2> /dev/null
190  then
191    echo "Branch counter record test [Failed record]"
192    err=1
193    return
194  fi
195  if ! perf report -i "${perfdata}" -D -q | grep -q "$br_cntr_output"
196  then
197    echo "Branch counter report test [Failed missing output]"
198    err=1
199    return
200  fi
201  if ! perf script -i "${perfdata}" -F +brstackinsn,+brcntr | grep -q "$br_cntr_script_output"
202  then
203    echo " Branch counter script test [Failed missing output]"
204    err=1
205    return
206  fi
207  echo "Branch counter test [Success]"
208}
209
210test_cgroup() {
211  echo "Cgroup sampling test"
212  if ! perf record -aB --synth=cgroup --all-cgroups -o "${perfdata}" ${testprog} 2> /dev/null
213  then
214    echo "Cgroup sampling [Skipped not supported]"
215    return
216  fi
217  if ! perf report -i "${perfdata}" -D | grep -q "CGROUP"
218  then
219    echo "Cgroup sampling [Failed missing output]"
220    err=1
221    return
222  fi
223  if ! perf script -i "${perfdata}" -F cgroup | grep -q -v "unknown"
224  then
225    echo "Cgroup sampling [Failed cannot resolve cgroup names]"
226    err=1
227    return
228  fi
229  echo "Cgroup sampling test [Success]"
230}
231
232test_leader_sampling() {
233  echo "Basic leader sampling test"
234  if ! perf record -o "${perfdata}" -e "{instructions,instructions}:Su" -- \
235    perf test -w brstack 2> /dev/null
236  then
237    echo "Leader sampling [Failed record]"
238    err=1
239    return
240  fi
241  index=0
242  perf script -i "${perfdata}" > $script_output
243  while IFS= read -r line
244  do
245    # Check if the two instruction counts are equal in each record
246    instructions=$(echo $line | awk '{for(i=1;i<=NF;i++) if($i=="instructions:") print $(i-1)}')
247    if [ $(($index%2)) -ne 0 ] && [ ${instructions}x != ${prev_instructions}x ]
248    then
249      echo "Leader sampling [Failed inconsistent instructions count]"
250      err=1
251      return
252    fi
253    index=$(($index+1))
254    prev_instructions=$instructions
255  done < $script_output
256  echo "Basic leader sampling test [Success]"
257}
258
259test_topdown_leader_sampling() {
260  echo "Topdown leader sampling test"
261  if ! perf stat -e "{slots,topdown-retiring}" true 2> /dev/null
262  then
263    echo "Topdown leader sampling [Skipped event parsing failed]"
264    return
265  fi
266  if ! perf record -o "${perfdata}" -e "{instructions,slots,topdown-retiring}:S" true 2> /dev/null
267  then
268    echo "Topdown leader sampling [Failed topdown events not reordered correctly]"
269    err=1
270    return
271  fi
272  echo "Topdown leader sampling test [Success]"
273}
274
275test_precise_max() {
276  echo "precise_max attribute test"
277  if ! perf stat -e "cycles,instructions" true 2> /dev/null
278  then
279    echo "precise_max attribute [Skipped no hardware events]"
280    return
281  fi
282  # Just to make sure it doesn't fail
283  if ! perf record -o "${perfdata}" -e "cycles:P" true 2> /dev/null
284  then
285    echo "precise_max attribute [Failed cycles:P event]"
286    err=1
287    return
288  fi
289  # On AMD, cycles and instructions events are treated differently
290  if ! perf record -o "${perfdata}" -e "instructions:P" true 2> /dev/null
291  then
292    echo "precise_max attribute [Failed instructions:P event]"
293    err=1
294    return
295  fi
296  echo "precise_max attribute test [Success]"
297}
298
299# raise the limit of file descriptors to minimum
300if [[ $default_fd_limit -lt $min_fd_limit ]]; then
301       ulimit -Sn $min_fd_limit
302fi
303
304test_per_thread
305test_register_capture
306test_system_wide
307test_workload
308test_branch_counter
309test_cgroup
310test_leader_sampling
311test_topdown_leader_sampling
312test_precise_max
313
314# restore the default value
315ulimit -Sn $default_fd_limit
316
317cleanup
318exit $err