Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/sh
0002 # Check Arm CoreSight trace data recording and synthesized samples
0003 
0004 # Uses the 'perf record' to record trace data with Arm CoreSight sinks;
0005 # then verify if there have any branch samples and instruction samples
0006 # are generated by CoreSight with 'perf script' and 'perf report'
0007 # commands.
0008 
0009 # SPDX-License-Identifier: GPL-2.0
0010 # Leo Yan <leo.yan@linaro.org>, 2020
0011 
0012 glb_err=0
0013 
0014 skip_if_no_cs_etm_event() {
0015         perf list | grep -q 'cs_etm//' && return 0
0016 
0017         # cs_etm event doesn't exist
0018         return 2
0019 }
0020 
0021 skip_if_no_cs_etm_event || exit 2
0022 
0023 perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
0024 file=$(mktemp /tmp/temporary_file.XXXXX)
0025 
0026 cleanup_files()
0027 {
0028         rm -f ${perfdata}
0029         rm -f ${file}
0030         rm -f "${perfdata}.old"
0031         trap - exit term int
0032         exit $glb_err
0033 }
0034 
0035 trap cleanup_files exit term int
0036 
0037 record_touch_file() {
0038         echo "Recording trace (only user mode) with path: CPU$2 => $1"
0039         rm -f $file
0040         perf record -o ${perfdata} -e cs_etm/@$1/u --per-thread \
0041                 -- taskset -c $2 touch $file > /dev/null 2>&1
0042 }
0043 
0044 perf_script_branch_samples() {
0045         echo "Looking at perf.data file for dumping branch samples:"
0046 
0047         # Below is an example of the branch samples dumping:
0048         #   touch  6512          1         branches:u:      ffffb220824c strcmp+0xc (/lib/aarch64-linux-gnu/ld-2.27.so)
0049         #   touch  6512          1         branches:u:      ffffb22082e0 strcmp+0xa0 (/lib/aarch64-linux-gnu/ld-2.27.so)
0050         #   touch  6512          1         branches:u:      ffffb2208320 strcmp+0xe0 (/lib/aarch64-linux-gnu/ld-2.27.so)
0051         perf script -F,-time -i ${perfdata} 2>&1 | \
0052                 egrep " +$1 +[0-9]+ .* +branches:(.*:)? +" > /dev/null 2>&1
0053 }
0054 
0055 perf_report_branch_samples() {
0056         echo "Looking at perf.data file for reporting branch samples:"
0057 
0058         # Below is an example of the branch samples reporting:
0059         #   73.04%    73.04%  touch    libc-2.27.so      [.] _dl_addr
0060         #    7.71%     7.71%  touch    libc-2.27.so      [.] getenv
0061         #    2.59%     2.59%  touch    ld-2.27.so        [.] strcmp
0062         perf report --stdio -i ${perfdata} 2>&1 | \
0063                 egrep " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 " > /dev/null 2>&1
0064 }
0065 
0066 perf_report_instruction_samples() {
0067         echo "Looking at perf.data file for instruction samples:"
0068 
0069         # Below is an example of the instruction samples reporting:
0070         #   68.12%  touch    libc-2.27.so   [.] _dl_addr
0071         #    5.80%  touch    libc-2.27.so   [.] getenv
0072         #    4.35%  touch    ld-2.27.so     [.] _dl_fixup
0073         perf report --itrace=i1000i --stdio -i ${perfdata} 2>&1 | \
0074                 egrep " +[0-9]+\.[0-9]+% +$1" > /dev/null 2>&1
0075 }
0076 
0077 arm_cs_report() {
0078         if [ $2 != 0 ]; then
0079                 echo "$1: FAIL"
0080                 glb_err=$2
0081         else
0082                 echo "$1: PASS"
0083         fi
0084 }
0085 
0086 is_device_sink() {
0087         # If the node of "enable_sink" is existed under the device path, this
0088         # means the device is a sink device.  Need to exclude 'tpiu' since it
0089         # cannot support perf PMU.
0090         echo "$1" | egrep -q -v "tpiu"
0091 
0092         if [ $? -eq 0 -a -e "$1/enable_sink" ]; then
0093 
0094                 pmu_dev="/sys/bus/event_source/devices/cs_etm/sinks/$2"
0095 
0096                 # Warn if the device is not supported by PMU
0097                 if ! [ -f $pmu_dev ]; then
0098                         echo "PMU doesn't support $pmu_dev"
0099                 fi
0100 
0101                 return 0
0102         fi
0103 
0104         # Otherwise, it's not a sink device
0105         return 1
0106 }
0107 
0108 arm_cs_iterate_devices() {
0109         for dev in $1/connections/out\:*; do
0110 
0111                 # Skip testing if it's not a directory
0112                 ! [ -d $dev ] && continue;
0113 
0114                 # Read out its symbol link file name
0115                 path=`readlink -f $dev`
0116 
0117                 # Extract device name from path, e.g.
0118                 #   path = '/sys/devices/platform/20010000.etf/tmc_etf0'
0119                 #     `> device_name = 'tmc_etf0'
0120                 device_name=$(basename $path)
0121 
0122                 if is_device_sink $path $device_name; then
0123 
0124                         record_touch_file $device_name $2 &&
0125                         perf_script_branch_samples touch &&
0126                         perf_report_branch_samples touch &&
0127                         perf_report_instruction_samples touch
0128 
0129                         err=$?
0130                         arm_cs_report "CoreSight path testing (CPU$2 -> $device_name)" $err
0131                 fi
0132 
0133                 arm_cs_iterate_devices $dev $2
0134         done
0135 }
0136 
0137 arm_cs_etm_traverse_path_test() {
0138         # Iterate for every ETM device
0139         for dev in /sys/bus/coresight/devices/etm*; do
0140 
0141                 # Find the ETM device belonging to which CPU
0142                 cpu=`cat $dev/cpu`
0143 
0144                 # Use depth-first search (DFS) to iterate outputs
0145                 arm_cs_iterate_devices $dev $cpu
0146         done
0147 }
0148 
0149 arm_cs_etm_system_wide_test() {
0150         echo "Recording trace with system wide mode"
0151         perf record -o ${perfdata} -e cs_etm// -a -- ls > /dev/null 2>&1
0152 
0153         perf_script_branch_samples perf &&
0154         perf_report_branch_samples perf &&
0155         perf_report_instruction_samples perf
0156 
0157         err=$?
0158         arm_cs_report "CoreSight system wide testing" $err
0159 }
0160 
0161 arm_cs_etm_snapshot_test() {
0162         echo "Recording trace with snapshot mode"
0163         perf record -o ${perfdata} -e cs_etm// -S \
0164                 -- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 &
0165         PERFPID=$!
0166 
0167         # Wait for perf program
0168         sleep 1
0169 
0170         # Send signal to snapshot trace data
0171         kill -USR2 $PERFPID
0172 
0173         # Stop perf program
0174         kill $PERFPID
0175         wait $PERFPID
0176 
0177         perf_script_branch_samples dd &&
0178         perf_report_branch_samples dd &&
0179         perf_report_instruction_samples dd
0180 
0181         err=$?
0182         arm_cs_report "CoreSight snapshot testing" $err
0183 }
0184 
0185 arm_cs_etm_traverse_path_test
0186 arm_cs_etm_system_wide_test
0187 arm_cs_etm_snapshot_test
0188 exit $glb_err