Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# perf kvm tests
3# SPDX-License-Identifier: GPL-2.0
4
5set -e
6
7err=0
8perfdata=$(mktemp /tmp/__perf_kvm_test.perf.data.XXXXX)
9qemu_pid_file=$(mktemp /tmp/__perf_kvm_test.qemu.pid.XXXXX)
10
11cleanup() {
12 rm -f "${perfdata}"
13 if [ -f "${qemu_pid_file}" ]; then
14 if [ -s "${qemu_pid_file}" ]; then
15 qemu_pid=$(cat "${qemu_pid_file}")
16 if [ -n "${qemu_pid}" ]; then
17 kill "${qemu_pid}" 2>/dev/null || true
18 fi
19 fi
20 rm -f "${qemu_pid_file}"
21 fi
22 trap - EXIT TERM INT
23}
24
25trap_cleanup() {
26 echo "Unexpected signal in ${FUNCNAME[1]}"
27 cleanup
28 exit 1
29}
30trap trap_cleanup EXIT TERM INT
31
32skip() {
33 echo "Skip: $1"
34 cleanup
35 exit 2
36}
37
38test_kvm_stat() {
39 echo "Testing perf kvm stat"
40
41 echo "Recording kvm events for pid ${qemu_pid}..."
42 if ! perf kvm stat record -p "${qemu_pid}" -o "${perfdata}" sleep 1; then
43 echo "Failed to record kvm events"
44 err=1
45 return
46 fi
47
48 echo "Reporting kvm events..."
49 if ! perf kvm -i "${perfdata}" stat report 2>&1 | grep -q "VM-EXIT"; then
50 echo "Failed to find VM-EXIT in report"
51 perf kvm -i "${perfdata}" stat report 2>&1
52 err=1
53 return
54 fi
55
56 echo "perf kvm stat test [Success]"
57}
58
59test_kvm_record_report() {
60 echo "Testing perf kvm record/report"
61
62 echo "Recording kvm profile for pid ${qemu_pid}..."
63 # Use --host to avoid needing guest symbols/mounts for this simple test
64 # We just want to verify the command runs and produces data
65 # We run in background and kill it because 'perf kvm record' appends options
66 # after the command, which breaks 'sleep' (e.g. it gets '-e cycles').
67 perf kvm --host record -p "${qemu_pid}" -o "${perfdata}" &
68 rec_pid=$!
69 sleep 1
70 kill -INT "${rec_pid}"
71 wait "${rec_pid}" || true
72
73 echo "Reporting kvm profile..."
74 # Check for some standard output from report
75 if ! perf kvm -i "${perfdata}" report --stdio 2>&1 | grep -q "Event count"; then
76 echo "Failed to report kvm profile"
77 perf kvm -i "${perfdata}" report --stdio 2>&1
78 err=1
79 return
80 fi
81
82 echo "perf kvm record/report test [Success]"
83}
84
85test_kvm_buildid_list() {
86 echo "Testing perf kvm buildid-list"
87
88 # We reuse the perf.data from the previous record test
89 if ! perf kvm --host -i "${perfdata}" buildid-list 2>&1 | grep -q "."; then
90 echo "Failed to list buildids"
91 perf kvm --host -i "${perfdata}" buildid-list 2>&1
92 err=1
93 return
94 fi
95
96 echo "perf kvm buildid-list test [Success]"
97}
98
99setup_qemu() {
100 # Find qemu
101 if [ "$(uname -m)" = "x86_64" ]; then
102 qemu="qemu-system-x86_64"
103 elif [ "$(uname -m)" = "aarch64" ]; then
104 qemu="qemu-system-aarch64"
105 elif [ "$(uname -m)" = "s390x" ]; then
106 qemu="qemu-system-s390x"
107 elif [ "$(uname -m)" = "ppc64le" ]; then
108 qemu="qemu-system-ppc64"
109 else
110 qemu="qemu-system-$(uname -m)"
111 fi
112
113 if ! which -s "$qemu"; then
114 skip "$qemu not found"
115 fi
116
117 if [ ! -r /dev/kvm ] || [ ! -w /dev/kvm ]; then
118 skip "/dev/kvm not accessible"
119 fi
120
121 if ! perf kvm stat record -o /dev/null -a sleep 0.01 >/dev/null 2>&1; then
122 skip "No permission to record kvm events"
123 fi
124
125 echo "Starting $qemu..."
126 # Start qemu in background, detached, with pidfile
127 # We use -display none -daemonize and a monitor to keep it alive/controllable if needed
128 # We don't need a real kernel, just KVM active.
129 if ! $qemu -enable-kvm -display none -daemonize -pidfile "${qemu_pid_file}" -monitor none; then
130 echo "Failed to start qemu"
131 err=1
132 return
133 fi
134
135 # Wait a bit for qemu to start
136 sleep 1
137 qemu_pid=$(cat "${qemu_pid_file}")
138
139 if ! kill -0 "${qemu_pid}" 2>/dev/null; then
140 echo "Qemu process failed to stay alive"
141 err=1
142 return
143 fi
144}
145
146setup_qemu
147if [ $err -eq 0 ]; then
148 test_kvm_stat
149 test_kvm_record_report
150 test_kvm_buildid_list
151fi
152
153cleanup
154exit $err