1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#!/bin/sh
# Check Arm SPE trace data recording and synthesized samples (exclusive)
# Uses the 'perf record' to record trace data of Arm SPE events;
# then verify if any SPE event samples are generated by SPE with
# 'perf script' and 'perf report' commands.
# SPDX-License-Identifier: GPL-2.0
# German Gomez <german.gomez@arm.com>, 2021
skip_if_no_arm_spe_event() {
perf list pmu | grep -E -q 'arm_spe_[0-9]+//' && return 0
# arm_spe event doesn't exist
return 2
}
skip_if_no_arm_spe_event || exit 2
perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
glb_err=0
cleanup_files()
{
rm -f ${perfdata}
rm -f ${perfdata}.old
exit $glb_err
}
trap cleanup_files EXIT TERM INT
arm_spe_report() {
if [ $2 = 0 ]; then
echo "$1: PASS"
elif [ $2 = 2 ]; then
echo "$1: SKIPPED"
else
echo "$1: FAIL"
glb_err=$2
fi
}
perf_script_samples() {
echo "Looking at perf.data file for dumping samples:"
# from arm-spe.c/arm_spe_synth_events()
events="(ld1-miss|ld1-access|llc-miss|lld-access|tlb-miss|tlb-access|branch-miss|remote-access|memory)"
# Below is an example of the samples dumping:
# dd 3048 [002] 1 l1d-access: ffffaa64999c __GI___libc_write+0x3c (/lib/aarch64-linux-gnu/libc-2.27.so)
# dd 3048 [002] 1 tlb-access: ffffaa64999c __GI___libc_write+0x3c (/lib/aarch64-linux-gnu/libc-2.27.so)
# dd 3048 [002] 1 memory: ffffaa64999c __GI___libc_write+0x3c (/lib/aarch64-linux-gnu/libc-2.27.so)
perf script -F,-time -i ${perfdata} 2>&1 | \
grep -E " +$1 +[0-9]+ .* +${events}:(.*:)? +" > /dev/null 2>&1
}
perf_report_samples() {
echo "Looking at perf.data file for reporting samples:"
# Below is an example of the samples reporting:
# 73.04% 73.04% dd libc-2.27.so [.] _dl_addr
# 7.71% 7.71% dd libc-2.27.so [.] getenv
# 2.59% 2.59% dd ld-2.27.so [.] strcmp
perf report --stdio -i ${perfdata} 2>&1 | \
grep -E " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 " > /dev/null 2>&1
}
arm_spe_snapshot_test() {
echo "Recording trace with snapshot mode $perfdata"
perf record -o ${perfdata} -e arm_spe// -S \
-- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 &
PERFPID=$!
# Wait for perf program
sleep 1
# Send signal to snapshot trace data
kill -USR2 $PERFPID
# Stop perf program
kill $PERFPID
wait $PERFPID
perf_script_samples dd &&
perf_report_samples dd
err=$?
arm_spe_report "SPE snapshot testing" $err
}
arm_spe_system_wide_test() {
echo "Recording trace with system-wide mode $perfdata"
perf record -o - -e dummy -a -B true > /dev/null 2>&1
if [ $? != 0 ]; then
arm_spe_report "SPE system-wide testing" 2
return
fi
perf record -o ${perfdata} -e arm_spe// -a --no-bpf-event \
-- dd if=/dev/zero of=/dev/null count=100000 > /dev/null 2>&1
perf_script_samples dd &&
perf_report_samples dd
err=$?
arm_spe_report "SPE system-wide testing" $err
}
arm_spe_discard_test() {
echo "SPE discard mode"
for f in /sys/bus/event_source/devices/arm_spe_*; do
if [ -e "$f/format/discard" ]; then
cpu=$(cut -c -1 "$f/cpumask")
break
fi
done
if [ -z $cpu ]; then
arm_spe_report "SPE discard mode not present" 2
return
fi
# Test can use wildcard SPE instance and Perf will only open the event
# on instances that have that format flag. But make sure the target
# runs on an instance with discard mode otherwise we're not testing
# anything.
perf record -o ${perfdata} -e arm_spe/discard/ -N -B --no-bpf-event \
-- taskset --cpu-list $cpu true
if perf report -i ${perfdata} --stats | grep 'AUX events\|AUXTRACE events'; then
arm_spe_report "SPE discard mode found unexpected data" 1
else
arm_spe_report "SPE discard mode" 0
fi
}
arm_spe_snapshot_test
arm_spe_system_wide_test
arm_spe_discard_test
exit $glb_err
|