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 144 145 146 147 148 149 150 151 152 153 154
|
#!/bin/bash
# perf kvm tests
# SPDX-License-Identifier: GPL-2.0
set -e
err=0
perfdata=$(mktemp /tmp/__perf_kvm_test.perf.data.XXXXX)
qemu_pid_file=$(mktemp /tmp/__perf_kvm_test.qemu.pid.XXXXX)
cleanup() {
rm -f "${perfdata}"
if [ -f "${qemu_pid_file}" ]; then
if [ -s "${qemu_pid_file}" ]; then
qemu_pid=$(cat "${qemu_pid_file}")
if [ -n "${qemu_pid}" ]; then
kill "${qemu_pid}" 2>/dev/null || true
fi
fi
rm -f "${qemu_pid_file}"
fi
trap - EXIT TERM INT
}
trap_cleanup() {
echo "Unexpected signal in ${FUNCNAME[1]}"
cleanup
exit 1
}
trap trap_cleanup EXIT TERM INT
skip() {
echo "Skip: $1"
cleanup
exit 2
}
test_kvm_stat() {
echo "Testing perf kvm stat"
echo "Recording kvm events for pid ${qemu_pid}..."
if ! perf kvm stat record -p "${qemu_pid}" -o "${perfdata}" sleep 1; then
echo "Failed to record kvm events"
err=1
return
fi
echo "Reporting kvm events..."
if ! perf kvm -i "${perfdata}" stat report 2>&1 | grep -q "VM-EXIT"; then
echo "Failed to find VM-EXIT in report"
perf kvm -i "${perfdata}" stat report 2>&1
err=1
return
fi
echo "perf kvm stat test [Success]"
}
test_kvm_record_report() {
echo "Testing perf kvm record/report"
echo "Recording kvm profile for pid ${qemu_pid}..."
# Use --host to avoid needing guest symbols/mounts for this simple test
# We just want to verify the command runs and produces data
# We run in background and kill it because 'perf kvm record' appends options
# after the command, which breaks 'sleep' (e.g. it gets '-e cycles').
perf kvm --host record -p "${qemu_pid}" -o "${perfdata}" &
rec_pid=$!
sleep 1
kill -INT "${rec_pid}"
wait "${rec_pid}" || true
echo "Reporting kvm profile..."
# Check for some standard output from report
if ! perf kvm -i "${perfdata}" report --stdio 2>&1 | grep -q "Event count"; then
echo "Failed to report kvm profile"
perf kvm -i "${perfdata}" report --stdio 2>&1
err=1
return
fi
echo "perf kvm record/report test [Success]"
}
test_kvm_buildid_list() {
echo "Testing perf kvm buildid-list"
# We reuse the perf.data from the previous record test
if ! perf kvm --host -i "${perfdata}" buildid-list 2>&1 | grep -q "."; then
echo "Failed to list buildids"
perf kvm --host -i "${perfdata}" buildid-list 2>&1
err=1
return
fi
echo "perf kvm buildid-list test [Success]"
}
setup_qemu() {
# Find qemu
if [ "$(uname -m)" = "x86_64" ]; then
qemu="qemu-system-x86_64"
elif [ "$(uname -m)" = "aarch64" ]; then
qemu="qemu-system-aarch64"
elif [ "$(uname -m)" = "s390x" ]; then
qemu="qemu-system-s390x"
elif [ "$(uname -m)" = "ppc64le" ]; then
qemu="qemu-system-ppc64"
else
qemu="qemu-system-$(uname -m)"
fi
if ! which -s "$qemu"; then
skip "$qemu not found"
fi
if [ ! -r /dev/kvm ] || [ ! -w /dev/kvm ]; then
skip "/dev/kvm not accessible"
fi
if ! perf kvm stat record -o /dev/null -a sleep 0.01 >/dev/null 2>&1; then
skip "No permission to record kvm events"
fi
echo "Starting $qemu..."
# Start qemu in background, detached, with pidfile
# We use -display none -daemonize and a monitor to keep it alive/controllable if needed
# We don't need a real kernel, just KVM active.
if ! $qemu -enable-kvm -display none -daemonize -pidfile "${qemu_pid_file}" -monitor none; then
echo "Failed to start qemu"
err=1
return
fi
# Wait a bit for qemu to start
sleep 1
qemu_pid=$(cat "${qemu_pid_file}")
if ! kill -0 "${qemu_pid}" 2>/dev/null; then
echo "Qemu process failed to stay alive"
err=1
return
fi
}
setup_qemu
if [ $err -eq 0 ]; then
test_kvm_stat
test_kvm_record_report
test_kvm_buildid_list
fi
cleanup
exit $err
|