| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- #!/bin/sh
- # perf stat tests
- # SPDX-License-Identifier: GPL-2.0
- set -e
- err=0
- test_default_stat() {
- echo "Basic stat command test"
- if ! perf stat true 2>&1 | grep -E -q "Performance counter stats for 'true':"
- then
- echo "Basic stat command test [Failed]"
- err=1
- return
- fi
- echo "Basic stat command test [Success]"
- }
- test_stat_record_report() {
- echo "stat record and report test"
- if ! perf stat record -o - true | perf stat report -i - 2>&1 | \
- grep -E -q "Performance counter stats for 'pipe':"
- then
- echo "stat record and report test [Failed]"
- err=1
- return
- fi
- echo "stat record and report test [Success]"
- }
- test_stat_record_script() {
- echo "stat record and script test"
- if ! perf stat record -o - true | perf script -i - 2>&1 | \
- grep -E -q "CPU[[:space:]]+THREAD[[:space:]]+VAL[[:space:]]+ENA[[:space:]]+RUN[[:space:]]+TIME[[:space:]]+EVENT"
- then
- echo "stat record and script test [Failed]"
- err=1
- return
- fi
- echo "stat record and script test [Success]"
- }
- test_stat_repeat_weak_groups() {
- echo "stat repeat weak groups test"
- if ! perf stat -e '{cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles}' \
- true 2>&1 | grep -q 'seconds time elapsed'
- then
- echo "stat repeat weak groups test [Skipped event parsing failed]"
- return
- fi
- if ! perf stat -r2 -e '{cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles}:W' \
- true > /dev/null 2>&1
- then
- echo "stat repeat weak groups test [Failed]"
- err=1
- return
- fi
- echo "stat repeat weak groups test [Success]"
- }
- test_topdown_groups() {
- # Topdown events must be grouped with the slots event first. Test that
- # parse-events reorders this.
- echo "Topdown event group test"
- if ! perf stat -e '{slots,topdown-retiring}' true > /dev/null 2>&1
- then
- echo "Topdown event group test [Skipped event parsing failed]"
- return
- fi
- if perf stat -e '{slots,topdown-retiring}' true 2>&1 | grep -E -q "<not supported>"
- then
- echo "Topdown event group test [Failed events not supported]"
- err=1
- return
- fi
- if perf stat -e '{topdown-retiring,slots}' true 2>&1 | grep -E -q "<not supported>"
- then
- echo "Topdown event group test [Failed slots not reordered first]"
- err=1
- return
- fi
- echo "Topdown event group test [Success]"
- }
- test_topdown_weak_groups() {
- # Weak groups break if the perf_event_open of multiple grouped events
- # fails. Breaking a topdown group causes the events to fail. Test a very large
- # grouping to see that the topdown events aren't broken out.
- echo "Topdown weak groups test"
- ok_grouping="{slots,topdown-bad-spec,topdown-be-bound,topdown-fe-bound,topdown-retiring},branch-instructions,branch-misses,bus-cycles,cache-misses,cache-references,cpu-cycles,instructions,mem-loads,mem-stores,ref-cycles,cache-misses,cache-references"
- if ! perf stat --no-merge -e "$ok_grouping" true > /dev/null 2>&1
- then
- echo "Topdown weak groups test [Skipped event parsing failed]"
- return
- fi
- group_needs_break="{slots,topdown-bad-spec,topdown-be-bound,topdown-fe-bound,topdown-retiring,branch-instructions,branch-misses,bus-cycles,cache-misses,cache-references,cpu-cycles,instructions,mem-loads,mem-stores,ref-cycles,cache-misses,cache-references}:W"
- if perf stat --no-merge -e "$group_needs_break" true 2>&1 | grep -E -q "<not supported>"
- then
- echo "Topdown weak groups test [Failed events not supported]"
- err=1
- return
- fi
- echo "Topdown weak groups test [Success]"
- }
- test_cputype() {
- # Test --cputype argument.
- echo "cputype test"
- # Bogus PMU should fail.
- if perf stat --cputype="123" -e instructions true > /dev/null 2>&1
- then
- echo "cputype test [Bogus PMU didn't fail]"
- err=1
- return
- fi
- # Find a known PMU for cputype.
- pmu=""
- for i in cpu cpu_atom armv8_pmuv3_0
- do
- if test -d "/sys/devices/$i"
- then
- pmu="$i"
- break
- fi
- if perf stat -e "$i/instructions/" true > /dev/null 2>&1
- then
- pmu="$i"
- break
- fi
- done
- if test "x$pmu" = "x"
- then
- echo "cputype test [Skipped known PMU not found]"
- return
- fi
- # Test running with cputype produces output.
- if ! perf stat --cputype="$pmu" -e instructions true 2>&1 | grep -E -q "instructions"
- then
- echo "cputype test [Failed count missed with given filter]"
- err=1
- return
- fi
- echo "cputype test [Success]"
- }
- test_hybrid() {
- # Test the default stat command on hybrid devices opens one cycles event for
- # each CPU type.
- echo "hybrid test"
- # Count the number of core PMUs, assume minimum of 1
- pmus=$(ls /sys/bus/event_source/devices/*/cpus 2>/dev/null | wc -l)
- if [ "$pmus" -lt 1 ]
- then
- pmus=1
- fi
- # Run default Perf stat
- cycles_events=$(perf stat -- true 2>&1 | grep -E "/cycles/[uH]*| cycles[:uH]* " -c)
- # The expectation is that default output will have a cycles events on each
- # hybrid PMU. In situations with no cycles PMU events, like virtualized, this
- # can fall back to task-clock and so the end count may be 0. Fail if neither
- # condition holds.
- if [ "$pmus" -ne "$cycles_events" ] && [ "0" -ne "$cycles_events" ]
- then
- echo "hybrid test [Found $pmus PMUs but $cycles_events cycles events. Failed]"
- err=1
- return
- fi
- echo "hybrid test [Success]"
- }
- test_default_stat
- test_stat_record_report
- test_stat_record_script
- test_stat_repeat_weak_groups
- test_topdown_groups
- test_topdown_weak_groups
- test_cputype
- test_hybrid
- exit $err
|