Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1#!/bin/sh
  2# Check Arm CoreSight trace data recording and synthesized samples (exclusive)
  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 pmu | 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 ] && [ -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/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
151arm_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
165arm_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
189arm_cs_etm_basic_test() {
190	echo "Recording trace with '$*'"
191	perf record -o ${perfdata} "$@" -m,8M -- 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
201arm_cs_etm_traverse_path_test
202arm_cs_etm_system_wide_test
203arm_cs_etm_snapshot_test
204
205# Test all combinations of per-thread, system-wide and normal mode with
206# and without timestamps
207arm_cs_etm_basic_test -e cs_etm/timestamp=0/ --per-thread
208arm_cs_etm_basic_test -e cs_etm/timestamp=1/ --per-thread
209arm_cs_etm_basic_test -e cs_etm/timestamp=0/ -a
210arm_cs_etm_basic_test -e cs_etm/timestamp=1/ -a
211arm_cs_etm_basic_test -e cs_etm/timestamp=0/
212arm_cs_etm_basic_test -e cs_etm/timestamp=1/
213
214exit $glb_err