Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
fork
Configure Feed
Select the types of activity you want to include in your feed.
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
12perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
13file=$(mktemp /tmp/temporary_file.XXXXX)
14glb_err=0
15
16skip_if_no_cs_etm_event() {
17 perf list | grep -q 'cs_etm//' && return 0
18
19 # cs_etm event doesn't exist
20 return 2
21}
22
23skip_if_no_cs_etm_event || exit 2
24
25cleanup_files()
26{
27 rm -f ${perfdata}
28 rm -f ${file}
29}
30
31trap cleanup_files exit
32
33record_touch_file() {
34 echo "Recording trace (only user mode) with path: CPU$2 => $1"
35 rm -f $file
36 perf record -o ${perfdata} -e cs_etm/@$1/u --per-thread \
37 -- taskset -c $2 touch $file > /dev/null 2>&1
38}
39
40perf_script_branch_samples() {
41 echo "Looking at perf.data file for dumping branch samples:"
42
43 # Below is an example of the branch samples dumping:
44 # touch 6512 1 branches:u: ffffb220824c strcmp+0xc (/lib/aarch64-linux-gnu/ld-2.27.so)
45 # touch 6512 1 branches:u: ffffb22082e0 strcmp+0xa0 (/lib/aarch64-linux-gnu/ld-2.27.so)
46 # touch 6512 1 branches:u: ffffb2208320 strcmp+0xe0 (/lib/aarch64-linux-gnu/ld-2.27.so)
47 perf script -F,-time -i ${perfdata} 2>&1 | \
48 egrep " +$1 +[0-9]+ .* +branches:(.*:)? +" > /dev/null 2>&1
49}
50
51perf_report_branch_samples() {
52 echo "Looking at perf.data file for reporting branch samples:"
53
54 # Below is an example of the branch samples reporting:
55 # 73.04% 73.04% touch libc-2.27.so [.] _dl_addr
56 # 7.71% 7.71% touch libc-2.27.so [.] getenv
57 # 2.59% 2.59% touch ld-2.27.so [.] strcmp
58 perf report --stdio -i ${perfdata} 2>&1 | \
59 egrep " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 " > /dev/null 2>&1
60}
61
62perf_report_instruction_samples() {
63 echo "Looking at perf.data file for instruction samples:"
64
65 # Below is an example of the instruction samples reporting:
66 # 68.12% touch libc-2.27.so [.] _dl_addr
67 # 5.80% touch libc-2.27.so [.] getenv
68 # 4.35% touch ld-2.27.so [.] _dl_fixup
69 perf report --itrace=i1000i --stdio -i ${perfdata} 2>&1 | \
70 egrep " +[0-9]+\.[0-9]+% +$1" > /dev/null 2>&1
71}
72
73arm_cs_report() {
74 if [ $2 != 0 ]; then
75 echo "$1: FAIL"
76 glb_err=$2
77 else
78 echo "$1: PASS"
79 fi
80}
81
82is_device_sink() {
83 # If the node of "enable_sink" is existed under the device path, this
84 # means the device is a sink device. Need to exclude 'tpiu' since it
85 # cannot support perf PMU.
86 echo "$1" | egrep -q -v "tpiu"
87
88 if [ $? -eq 0 -a -e "$1/enable_sink" ]; then
89
90 pmu_dev="/sys/bus/event_source/devices/cs_etm/sinks/$2"
91
92 # Warn if the device is not supported by PMU
93 if ! [ -f $pmu_dev ]; then
94 echo "PMU doesn't support $pmu_dev"
95 fi
96
97 return 0
98 fi
99
100 # Otherwise, it's not a sink device
101 return 1
102}
103
104arm_cs_iterate_devices() {
105 for dev in $1/connections/out\:*; do
106
107 # Skip testing if it's not a directory
108 ! [ -d $dev ] && continue;
109
110 # Read out its symbol link file name
111 path=`readlink -f $dev`
112
113 # Extract device name from path, e.g.
114 # path = '/sys/devices/platform/20010000.etf/tmc_etf0'
115 # `> device_name = 'tmc_etf0'
116 device_name=$(basename $path)
117
118 if is_device_sink $path $device_name; then
119
120 record_touch_file $device_name $2 &&
121 perf_script_branch_samples touch &&
122 perf_report_branch_samples touch &&
123 perf_report_instruction_samples touch
124
125 err=$?
126 arm_cs_report "CoreSight path testing (CPU$2 -> $device_name)" $err
127 fi
128
129 arm_cs_iterate_devices $dev $2
130 done
131}
132
133arm_cs_etm_traverse_path_test() {
134 # Iterate for every ETM device
135 for dev in /sys/bus/coresight/devices/etm*; do
136
137 # Find the ETM device belonging to which CPU
138 cpu=`cat $dev/cpu`
139
140 # Use depth-first search (DFS) to iterate outputs
141 arm_cs_iterate_devices $dev $cpu
142 done
143}
144
145arm_cs_etm_system_wide_test() {
146 echo "Recording trace with system wide mode"
147 perf record -o ${perfdata} -e cs_etm// -a -- ls > /dev/null 2>&1
148
149 perf_script_branch_samples perf &&
150 perf_report_branch_samples perf &&
151 perf_report_instruction_samples perf
152
153 err=$?
154 arm_cs_report "CoreSight system wide testing" $err
155}
156
157arm_cs_etm_snapshot_test() {
158 echo "Recording trace with snapshot mode"
159 perf record -o ${perfdata} -e cs_etm// -S \
160 -- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 &
161 PERFPID=$!
162
163 # Wait for perf program
164 sleep 1
165
166 # Send signal to snapshot trace data
167 kill -USR2 $PERFPID
168
169 # Stop perf program
170 kill $PERFPID
171 wait $PERFPID
172
173 perf_script_branch_samples dd &&
174 perf_report_branch_samples dd &&
175 perf_report_instruction_samples dd
176
177 err=$?
178 arm_cs_report "CoreSight snapshot testing" $err
179}
180
181arm_cs_etm_traverse_path_test
182arm_cs_etm_system_wide_test
183arm_cs_etm_snapshot_test
184exit $glb_err