xref: /linux/tools/perf/tests/shell/stat.sh (revision 6490dda55dcabbd5cf408387f932c9343a22c872)
1#!/bin/sh
2# perf stat tests
3# SPDX-License-Identifier: GPL-2.0
4
5set -e
6
7err=0
8test_default_stat() {
9  echo "Basic stat command test"
10  if ! perf stat true 2>&1 | grep -E -q "Performance counter stats for 'true':"
11  then
12    echo "Basic stat command test [Failed]"
13    err=1
14    return
15  fi
16  echo "Basic stat command test [Success]"
17}
18
19test_stat_record_report() {
20  echo "stat record and report test"
21  if ! perf stat record -o - true | perf stat report -i - 2>&1 | \
22    grep -E -q "Performance counter stats for 'pipe':"
23  then
24    echo "stat record and report test [Failed]"
25    err=1
26    return
27  fi
28  echo "stat record and report test [Success]"
29}
30
31test_stat_record_script() {
32  echo "stat record and script test"
33  if ! perf stat record -o - true | perf script -i - 2>&1 | \
34    grep -E -q "CPU[[:space:]]+THREAD[[:space:]]+VAL[[:space:]]+ENA[[:space:]]+RUN[[:space:]]+TIME[[:space:]]+EVENT"
35  then
36    echo "stat record and script test [Failed]"
37    err=1
38    return
39  fi
40  echo "stat record and script test [Success]"
41}
42
43test_stat_repeat_weak_groups() {
44  echo "stat repeat weak groups test"
45  if ! perf stat -e '{cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles}' \
46     true 2>&1 | grep -q 'seconds time elapsed'
47  then
48    echo "stat repeat weak groups test [Skipped event parsing failed]"
49    return
50  fi
51  if ! perf stat -r2 -e '{cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles,cycles}:W' \
52    true > /dev/null 2>&1
53  then
54    echo "stat repeat weak groups test [Failed]"
55    err=1
56    return
57  fi
58  echo "stat repeat weak groups test [Success]"
59}
60
61test_topdown_groups() {
62  # Topdown events must be grouped with the slots event first. Test that
63  # parse-events reorders this.
64  echo "Topdown event group test"
65  if ! perf stat -e '{slots,topdown-retiring}' true > /dev/null 2>&1
66  then
67    echo "Topdown event group test [Skipped event parsing failed]"
68    return
69  fi
70  if perf stat -e '{slots,topdown-retiring}' true 2>&1 | grep -E -q "<not supported>"
71  then
72    echo "Topdown event group test [Failed events not supported]"
73    err=1
74    return
75  fi
76  if perf stat -e '{topdown-retiring,slots}' true 2>&1 | grep -E -q "<not supported>"
77  then
78    echo "Topdown event group test [Failed slots not reordered first]"
79    err=1
80    return
81  fi
82  echo "Topdown event group test [Success]"
83}
84
85test_topdown_weak_groups() {
86  # Weak groups break if the perf_event_open of multiple grouped events
87  # fails. Breaking a topdown group causes the events to fail. Test a very large
88  # grouping to see that the topdown events aren't broken out.
89  echo "Topdown weak groups test"
90  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"
91  if ! perf stat --no-merge -e "$ok_grouping" true > /dev/null 2>&1
92  then
93    echo "Topdown weak groups test [Skipped event parsing failed]"
94    return
95  fi
96  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"
97  if perf stat --no-merge -e "$group_needs_break" true 2>&1 | grep -E -q "<not supported>"
98  then
99    echo "Topdown weak groups test [Failed events not supported]"
100    err=1
101    return
102  fi
103  echo "Topdown weak groups test [Success]"
104}
105
106test_cputype() {
107  # Test --cputype argument.
108  echo "cputype test"
109
110  # Bogus PMU should fail.
111  if perf stat --cputype="123" -e instructions true > /dev/null 2>&1
112  then
113    echo "cputype test [Bogus PMU didn't fail]"
114    err=1
115    return
116  fi
117
118  # Find a known PMU for cputype.
119  pmu=""
120  devs="/sys/bus/event_source/devices"
121  for i in $devs/cpu $devs/cpu_atom $devs/armv8_pmuv3_0 $devs/armv8_cortex_*
122  do
123    i_base=$(basename "$i")
124    if test -d "$i"
125    then
126      pmu="$i_base"
127      break
128    fi
129    if perf stat -e "$i_base/instructions/" true > /dev/null 2>&1
130    then
131      pmu="$i_base"
132      break
133    fi
134  done
135  if test "x$pmu" = "x"
136  then
137    echo "cputype test [Skipped known PMU not found]"
138    return
139  fi
140
141  # Test running with cputype produces output.
142  if ! perf stat --cputype="$pmu" -e instructions true 2>&1 | grep -E -q "instructions"
143  then
144    echo "cputype test [Failed count missed with given filter]"
145    err=1
146    return
147  fi
148  echo "cputype test [Success]"
149}
150
151test_hybrid() {
152  # Test the default stat command on hybrid devices opens one cycles event for
153  # each CPU type.
154  echo "hybrid test"
155
156  # Count the number of core PMUs, assume minimum of 1
157  pmus=$(ls /sys/bus/event_source/devices/*/cpus 2>/dev/null | wc -l)
158  if [ "$pmus" -lt 1 ]
159  then
160    pmus=1
161  fi
162
163  # Run default Perf stat
164  cycles_events=$(perf stat -- true 2>&1 | grep -E "/cycles/|  cycles  " | wc -l)
165
166  if [ "$pmus" -ne "$cycles_events" ]
167  then
168    echo "hybrid test [Found $pmus PMUs but $cycles_events cycles events. Failed]"
169    err=1
170    return
171  fi
172  echo "hybrid test [Success]"
173}
174
175test_default_stat
176test_stat_record_report
177test_stat_record_script
178test_stat_repeat_weak_groups
179test_topdown_groups
180test_topdown_weak_groups
181test_cputype
182test_hybrid
183exit $err
184