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