perf tools: Fix spelling mistake "parametrized" -> "parameterized"
[linux-2.6-microblaze.git] / tools / perf / tests / shell / test_arm_coresight.sh
1 #!/bin/sh
2 # Check Arm CoreSight trace data recording and synthesized samples
3
4 # Uses the 'perf record' to record trace data with Arm CoreSight sinks;
5 # then verify if there have any branch samples and instruction samples
6 # are generated by CoreSight with 'perf script' and 'perf report'
7 # commands.
8
9 # SPDX-License-Identifier: GPL-2.0
10 # Leo Yan <leo.yan@linaro.org>, 2020
11
12 glb_err=0
13
14 skip_if_no_cs_etm_event() {
15         perf list | grep -q 'cs_etm//' && return 0
16
17         # cs_etm event doesn't exist
18         return 2
19 }
20
21 skip_if_no_cs_etm_event || exit 2
22
23 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
24 file=$(mktemp /tmp/temporary_file.XXXXX)
25
26 cleanup_files()
27 {
28         rm -f ${perfdata}
29         rm -f ${file}
30         rm -f "${perfdata}.old"
31         trap - EXIT TERM INT
32         exit $glb_err
33 }
34
35 trap cleanup_files EXIT TERM INT
36
37 record_touch_file() {
38         echo "Recording trace (only user mode) with path: CPU$2 => $1"
39         rm -f $file
40         perf record -o ${perfdata} -e cs_etm/@$1/u --per-thread \
41                 -- taskset -c $2 touch $file > /dev/null 2>&1
42 }
43
44 perf_script_branch_samples() {
45         echo "Looking at perf.data file for dumping branch samples:"
46
47         # Below is an example of the branch samples dumping:
48         #   touch  6512          1         branches:u:      ffffb220824c strcmp+0xc (/lib/aarch64-linux-gnu/ld-2.27.so)
49         #   touch  6512          1         branches:u:      ffffb22082e0 strcmp+0xa0 (/lib/aarch64-linux-gnu/ld-2.27.so)
50         #   touch  6512          1         branches:u:      ffffb2208320 strcmp+0xe0 (/lib/aarch64-linux-gnu/ld-2.27.so)
51         perf script -F,-time -i ${perfdata} 2>&1 | \
52                 grep -E " +$1 +[0-9]+ .* +branches:(.*:)? +" > /dev/null 2>&1
53 }
54
55 perf_report_branch_samples() {
56         echo "Looking at perf.data file for reporting branch samples:"
57
58         # Below is an example of the branch samples reporting:
59         #   73.04%    73.04%  touch    libc-2.27.so      [.] _dl_addr
60         #    7.71%     7.71%  touch    libc-2.27.so      [.] getenv
61         #    2.59%     2.59%  touch    ld-2.27.so        [.] strcmp
62         perf report --stdio -i ${perfdata} 2>&1 | \
63                 grep -E " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 " > /dev/null 2>&1
64 }
65
66 perf_report_instruction_samples() {
67         echo "Looking at perf.data file for instruction samples:"
68
69         # Below is an example of the instruction samples reporting:
70         #   68.12%  touch    libc-2.27.so   [.] _dl_addr
71         #    5.80%  touch    libc-2.27.so   [.] getenv
72         #    4.35%  touch    ld-2.27.so     [.] _dl_fixup
73         perf report --itrace=i20i --stdio -i ${perfdata} 2>&1 | \
74                 grep -E " +[0-9]+\.[0-9]+% +$1" > /dev/null 2>&1
75 }
76
77 arm_cs_report() {
78         if [ $2 != 0 ]; then
79                 echo "$1: FAIL"
80                 glb_err=$2
81         else
82                 echo "$1: PASS"
83         fi
84 }
85
86 is_device_sink() {
87         # If the node of "enable_sink" is existed under the device path, this
88         # means the device is a sink device.  Need to exclude 'tpiu' since it
89         # cannot support perf PMU.
90         echo "$1" | grep -E -q -v "tpiu"
91
92         if [ $? -eq 0 ] && [ -e "$1/enable_sink" ]; then
93
94                 pmu_dev="/sys/bus/event_source/devices/cs_etm/sinks/$2"
95
96                 # Warn if the device is not supported by PMU
97                 if ! [ -f $pmu_dev ]; then
98                         echo "PMU doesn't support $pmu_dev"
99                 fi
100
101                 return 0
102         fi
103
104         # Otherwise, it's not a sink device
105         return 1
106 }
107
108 arm_cs_iterate_devices() {
109         for dev in $1/connections/out\:*; do
110
111                 # Skip testing if it's not a directory
112                 ! [ -d $dev ] && continue;
113
114                 # Read out its symbol link file name
115                 path=`readlink -f $dev`
116
117                 # Extract device name from path, e.g.
118                 #   path = '/sys/devices/platform/20010000.etf/tmc_etf0'
119                 #     `> device_name = 'tmc_etf0'
120                 device_name=$(basename $path)
121
122                 if is_device_sink $path $device_name; then
123
124                         record_touch_file $device_name $2 &&
125                         perf_script_branch_samples touch &&
126                         perf_report_branch_samples touch &&
127                         perf_report_instruction_samples touch
128
129                         err=$?
130                         arm_cs_report "CoreSight path testing (CPU$2 -> $device_name)" $err
131                 fi
132
133                 arm_cs_iterate_devices $dev $2
134         done
135 }
136
137 arm_cs_etm_traverse_path_test() {
138         # Iterate for every ETM device
139         for dev in /sys/bus/event_source/devices/cs_etm/cpu*; do
140                 # Canonicalize the path
141                 dev=`readlink -f $dev`
142
143                 # Find the ETM device belonging to which CPU
144                 cpu=`cat $dev/cpu`
145
146                 # Use depth-first search (DFS) to iterate outputs
147                 arm_cs_iterate_devices $dev $cpu
148         done
149 }
150
151 arm_cs_etm_system_wide_test() {
152         echo "Recording trace with system wide mode"
153         perf record -o ${perfdata} -e cs_etm// -a -- ls > /dev/null 2>&1
154
155         # System-wide mode should include perf samples so test for that
156         # instead of ls
157         perf_script_branch_samples perf &&
158         perf_report_branch_samples perf &&
159         perf_report_instruction_samples perf
160
161         err=$?
162         arm_cs_report "CoreSight system wide testing" $err
163 }
164
165 arm_cs_etm_snapshot_test() {
166         echo "Recording trace with snapshot mode"
167         perf record -o ${perfdata} -e cs_etm// -S \
168                 -- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 &
169         PERFPID=$!
170
171         # Wait for perf program
172         sleep 1
173
174         # Send signal to snapshot trace data
175         kill -USR2 $PERFPID
176
177         # Stop perf program
178         kill $PERFPID
179         wait $PERFPID
180
181         perf_script_branch_samples dd &&
182         perf_report_branch_samples dd &&
183         perf_report_instruction_samples dd
184
185         err=$?
186         arm_cs_report "CoreSight snapshot testing" $err
187 }
188
189 arm_cs_etm_basic_test() {
190         echo "Recording trace with '$*'"
191         perf record -o ${perfdata} "$@" -- ls > /dev/null 2>&1
192
193         perf_script_branch_samples ls &&
194         perf_report_branch_samples ls &&
195         perf_report_instruction_samples ls
196
197         err=$?
198         arm_cs_report "CoreSight basic testing with '$*'" $err
199 }
200
201 arm_cs_etm_traverse_path_test
202 arm_cs_etm_system_wide_test
203 arm_cs_etm_snapshot_test
204
205 # Test all combinations of per-thread, system-wide and normal mode with
206 # and without timestamps
207 arm_cs_etm_basic_test -e cs_etm/timestamp=0/ --per-thread
208 arm_cs_etm_basic_test -e cs_etm/timestamp=1/ --per-thread
209 arm_cs_etm_basic_test -e cs_etm/timestamp=0/ -a
210 arm_cs_etm_basic_test -e cs_etm/timestamp=1/ -a
211 arm_cs_etm_basic_test -e cs_etm/timestamp=0/
212 arm_cs_etm_basic_test -e cs_etm/timestamp=1/
213
214 exit $glb_err