2 # perf record tests (exclusive)
3 # SPDX-License-Identifier: GPL-2.0
7 shelldir
=$
(dirname "$0")
8 # shellcheck source=lib/waiting.sh
9 .
"${shelldir}"/lib
/waiting.sh
11 # shellcheck source=lib/perf_has_symbol.sh
12 .
"${shelldir}"/lib
/perf_has_symbol.sh
16 skip_test_missing_symbol
${testsym}
19 perfdata
=$
(mktemp
/tmp
/__perf_test.perf.data.XXXXX
)
20 script_output
=$
(mktemp
/tmp
/__perf_test.perf.data.XXXXX.
script)
21 testprog
="perf test -w thloop"
22 cpu_pmu_dir
="/sys/bus/event_source/devices/cpu*"
23 br_cntr_file
="/caps/branch_counter_nr"
24 br_cntr_output
="branch stack counters"
25 br_cntr_script_output
="br_cntr: A"
27 default_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
34 min_fd_limit
=$
(($
(getconf _NPROCESSORS_ONLN
) * 16))
38 rm -rf "${perfdata}".old
47 trap trap_cleanup EXIT TERM INT
50 echo "Basic --per-thread mode test"
51 if ! perf record
-o /dev
/null
--quiet ${testprog} 2> /dev
/null
53 echo "Per-thread record [Skipped event not supported]"
56 if ! perf record
--per-thread -o "${perfdata}" ${testprog} 2> /dev
/null
58 echo "Per-thread record [Failed record]"
62 if ! perf report
-i "${perfdata}" -q |
grep -q "${testsym}"
64 echo "Per-thread record [Failed missing output]"
69 # run the test program in background (for 30 seconds)
75 wait_for_threads
${TESTPID} 2
76 perf record
-p "${TESTPID}" --per-thread -o "${perfdata}" sleep 1 2> /dev
/null
79 if [ ! -e "${perfdata}" ]
81 echo "Per-thread record [Failed record -p]"
85 if ! perf report
-i "${perfdata}" -q |
grep -q "${testsym}"
87 echo "Per-thread record [Failed -p missing output]"
92 echo "Basic --per-thread mode test [Success]"
95 test_register_capture
() {
96 echo "Register capture test"
97 if ! perf list pmu |
grep -q 'br_inst_retired.near_call'
99 echo "Register capture test [Skipped missing event]"
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'
104 echo "Register capture test [Skipped missing registers]"
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 \
112 echo "Register capture test [Failed missing output]"
116 echo "Register capture test [Success]"
120 echo "Basic --system-wide mode test"
121 if ! perf record
-aB --synth=no
-o "${perfdata}" ${testprog} 2> /dev
/null
123 echo "System-wide record [Skipped not supported]"
126 if ! perf report
-i "${perfdata}" -q |
grep -q "${testsym}"
128 echo "System-wide record [Failed missing output]"
132 if ! perf record
-aB --synth=no
-e cpu-clock
,cs
--threads=cpu \
133 -o "${perfdata}" ${testprog} 2> /dev
/null
135 echo "System-wide record [Failed record --threads option]"
139 if ! perf report
-i "${perfdata}" -q |
grep -q "${testsym}"
141 echo "System-wide record [Failed --threads missing output]"
145 echo "Basic --system-wide mode test [Success]"
149 echo "Basic target workload test"
150 if ! perf record
-o "${perfdata}" ${testprog} 2> /dev
/null
152 echo "Workload record [Failed record]"
156 if ! perf report
-i "${perfdata}" -q |
grep -q "${testsym}"
158 echo "Workload record [Failed missing output]"
162 if ! perf record
-e cpu-clock
,cs
--threads=package \
163 -o "${perfdata}" ${testprog} 2> /dev
/null
165 echo "Workload record [Failed record --threads option]"
169 if ! perf report
-i "${perfdata}" -q |
grep -q "${testsym}"
171 echo "Workload record [Failed --threads missing output]"
175 echo "Basic target workload test [Success]"
178 test_branch_counter
() {
179 echo "Branch counter test"
180 # Check if the branch counter feature is supported
181 for dir
in $cpu_pmu_dir
183 if [ ! -e "$dir$br_cntr_file" ]
185 echo "branch counter feature not supported on all core PMUs ($dir) [Skipped]"
189 if ! perf record
-o "${perfdata}" -e "{branches:p,instructions}" -j any
,counter
${testprog} 2> /dev
/null
191 echo "Branch counter record test [Failed record]"
195 if ! perf report
-i "${perfdata}" -D -q |
grep -q "$br_cntr_output"
197 echo "Branch counter report test [Failed missing output]"
201 if ! perf
script -i "${perfdata}" -F +brstackinsn
,+brcntr |
grep -q "$br_cntr_script_output"
203 echo " Branch counter script test [Failed missing output]"
207 echo "Branch counter test [Success]"
211 echo "Cgroup sampling test"
212 if ! perf record
-aB --synth=cgroup
--all-cgroups -o "${perfdata}" ${testprog} 2> /dev
/null
214 echo "Cgroup sampling [Skipped not supported]"
217 if ! perf report
-i "${perfdata}" -D |
grep -q "CGROUP"
219 echo "Cgroup sampling [Failed missing output]"
223 if ! perf
script -i "${perfdata}" -F cgroup |
grep -q -v "unknown"
225 echo "Cgroup sampling [Failed cannot resolve cgroup names]"
229 echo "Cgroup sampling test [Success]"
232 test_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
237 echo "Leader sampling [Failed record]"
242 perf
script -i "${perfdata}" > $script_output
243 while IFS
= read -r line
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
]
249 echo "Leader sampling [Failed inconsistent instructions count]"
254 prev_instructions
=$instructions
255 done < $script_output
256 echo "Basic leader sampling test [Success]"
259 test_topdown_leader_sampling
() {
260 echo "Topdown leader sampling test"
261 if ! perf stat
-e "{slots,topdown-retiring}" true
2> /dev
/null
263 echo "Topdown leader sampling [Skipped event parsing failed]"
266 if ! perf record
-o "${perfdata}" -e "{instructions,slots,topdown-retiring}:S" true
2> /dev
/null
268 echo "Topdown leader sampling [Failed topdown events not reordered correctly]"
272 echo "Topdown leader sampling test [Success]"
276 echo "precise_max attribute test"
277 if ! perf stat
-e "cycles,instructions" true
2> /dev
/null
279 echo "precise_max attribute [Skipped no hardware events]"
282 # Just to make sure it doesn't fail
283 if ! perf record
-o "${perfdata}" -e "cycles:P" true
2> /dev
/null
285 echo "precise_max attribute [Failed cycles:P event]"
289 # On AMD, cycles and instructions events are treated differently
290 if ! perf record
-o "${perfdata}" -e "instructions:P" true
2> /dev
/null
292 echo "precise_max attribute [Failed instructions:P event]"
296 echo "precise_max attribute test [Success]"
299 # raise the limit of file descriptors to minimum
300 if [[ $default_fd_limit -lt $min_fd_limit ]]; then
301 ulimit -Sn $min_fd_limit
305 test_register_capture
311 test_topdown_leader_sampling
314 # restore the default value
315 ulimit -Sn $default_fd_limit