Loading...
Note: File does not exist in v4.6.
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
12glb_err=0
13
14skip_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
21skip_if_no_cs_etm_event || exit 2
22
23perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
24file=$(mktemp /tmp/temporary_file.XXXXX)
25
26cleanup_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
35trap cleanup_files exit term int
36
37record_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
44perf_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
55perf_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
66perf_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
77arm_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
86is_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 -a -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
108arm_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
137arm_cs_etm_traverse_path_test() {
138 # Iterate for every ETM device
139 for dev in /sys/bus/coresight/devices/etm*; do
140
141 # Find the ETM device belonging to which CPU
142 cpu=`cat $dev/cpu`
143
144 # Use depth-first search (DFS) to iterate outputs
145 arm_cs_iterate_devices $dev $cpu
146 done
147}
148
149arm_cs_etm_system_wide_test() {
150 echo "Recording trace with system wide mode"
151 perf record -o ${perfdata} -e cs_etm// -a -- ls > /dev/null 2>&1
152
153 perf_script_branch_samples perf &&
154 perf_report_branch_samples perf &&
155 perf_report_instruction_samples perf
156
157 err=$?
158 arm_cs_report "CoreSight system wide testing" $err
159}
160
161arm_cs_etm_snapshot_test() {
162 echo "Recording trace with snapshot mode"
163 perf record -o ${perfdata} -e cs_etm// -S \
164 -- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 &
165 PERFPID=$!
166
167 # Wait for perf program
168 sleep 1
169
170 # Send signal to snapshot trace data
171 kill -USR2 $PERFPID
172
173 # Stop perf program
174 kill $PERFPID
175 wait $PERFPID
176
177 perf_script_branch_samples dd &&
178 perf_report_branch_samples dd &&
179 perf_report_instruction_samples dd
180
181 err=$?
182 arm_cs_report "CoreSight snapshot testing" $err
183}
184
185arm_cs_etm_traverse_path_test
186arm_cs_etm_system_wide_test
187arm_cs_etm_snapshot_test
188exit $glb_err