2022-04-14 04:46:42 +03:00
|
|
|
#!/bin/sh
|
|
|
|
# perf record tests
|
|
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
2022-10-20 20:26:39 +03:00
|
|
|
shelldir=$(dirname "$0")
|
|
|
|
. "${shelldir}"/lib/waiting.sh
|
|
|
|
|
2022-04-14 04:46:42 +03:00
|
|
|
err=0
|
2022-05-05 21:25:05 +03:00
|
|
|
perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX)
|
2022-10-20 20:26:38 +03:00
|
|
|
testprog=$(mktemp /tmp/__perf_test.prog.XXXXXX)
|
|
|
|
testsym="test_loop"
|
2022-05-05 21:25:05 +03:00
|
|
|
|
|
|
|
cleanup() {
|
2022-10-20 20:26:37 +03:00
|
|
|
rm -f "${perfdata}"
|
|
|
|
rm -f "${perfdata}".old
|
2022-10-20 20:26:38 +03:00
|
|
|
|
|
|
|
if [ "${testprog}" != "true" ]; then
|
|
|
|
rm -f "${testprog}"
|
|
|
|
fi
|
|
|
|
|
2022-10-20 20:26:37 +03:00
|
|
|
trap - EXIT TERM INT
|
2022-05-05 21:25:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
trap_cleanup() {
|
|
|
|
cleanup
|
|
|
|
exit 1
|
|
|
|
}
|
2022-10-20 20:26:37 +03:00
|
|
|
trap trap_cleanup EXIT TERM INT
|
2022-05-05 21:25:05 +03:00
|
|
|
|
2022-10-20 20:26:38 +03:00
|
|
|
build_test_program() {
|
|
|
|
if ! [ -x "$(command -v cc)" ]; then
|
|
|
|
# No CC found. Fall back to 'true'
|
|
|
|
testprog=true
|
|
|
|
testsym=true
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Build a test program"
|
|
|
|
cat <<EOF | cc -o ${testprog} -xc - -pthread
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
|
|
|
|
void test_loop(void) {
|
|
|
|
volatile int count = 1000000;
|
|
|
|
|
|
|
|
while (count--)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *thfunc(void *arg) {
|
|
|
|
int forever = *(int *)arg;
|
|
|
|
|
|
|
|
do {
|
|
|
|
test_loop();
|
|
|
|
} while (forever);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
pthread_t th;
|
|
|
|
int forever = 0;
|
|
|
|
|
|
|
|
if (argc > 1)
|
|
|
|
forever = atoi(argv[1]);
|
|
|
|
|
|
|
|
pthread_create(&th, NULL, thfunc, &forever);
|
|
|
|
test_loop();
|
|
|
|
pthread_join(th, NULL);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
2022-04-14 04:46:42 +03:00
|
|
|
test_per_thread() {
|
|
|
|
echo "Basic --per-thread mode test"
|
2022-10-20 20:26:38 +03:00
|
|
|
if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null
|
2022-05-05 21:25:05 +03:00
|
|
|
then
|
2022-10-20 20:26:36 +03:00
|
|
|
echo "Per-thread record [Skipped event not supported]"
|
2022-05-05 21:25:05 +03:00
|
|
|
if [ $err -ne 1 ]
|
|
|
|
then
|
|
|
|
err=2
|
|
|
|
fi
|
|
|
|
return
|
|
|
|
fi
|
2022-10-20 20:26:38 +03:00
|
|
|
if ! perf record --per-thread -o "${perfdata}" ${testprog} 2> /dev/null
|
2022-05-05 21:25:05 +03:00
|
|
|
then
|
2022-10-20 20:26:36 +03:00
|
|
|
echo "Per-thread record [Failed record]"
|
2022-05-05 21:25:05 +03:00
|
|
|
err=1
|
|
|
|
return
|
|
|
|
fi
|
2022-10-20 20:26:38 +03:00
|
|
|
if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
|
2022-05-05 21:25:05 +03:00
|
|
|
then
|
|
|
|
echo "Per-thread record [Failed missing output]"
|
|
|
|
err=1
|
|
|
|
return
|
|
|
|
fi
|
2022-10-20 20:26:39 +03:00
|
|
|
|
|
|
|
# run the test program in background (forever)
|
|
|
|
${testprog} 1 &
|
|
|
|
TESTPID=$!
|
|
|
|
|
|
|
|
rm -f "${perfdata}"
|
|
|
|
|
|
|
|
wait_for_threads ${TESTPID} 2
|
|
|
|
perf record -p "${TESTPID}" --per-thread -o "${perfdata}" sleep 1 2> /dev/null
|
|
|
|
kill ${TESTPID}
|
|
|
|
|
|
|
|
if [ ! -e "${perfdata}" ]
|
|
|
|
then
|
|
|
|
echo "Per-thread record [Failed record -p]"
|
|
|
|
err=1
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
if ! perf report -i "${perfdata}" -q | grep -q "${testsym}"
|
|
|
|
then
|
|
|
|
echo "Per-thread record [Failed -p missing output]"
|
|
|
|
err=1
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2022-04-14 04:46:42 +03:00
|
|
|
echo "Basic --per-thread mode test [Success]"
|
|
|
|
}
|
|
|
|
|
|
|
|
test_register_capture() {
|
|
|
|
echo "Register capture test"
|
2022-10-20 20:26:37 +03:00
|
|
|
if ! perf list | grep -q 'br_inst_retired.near_call'
|
2022-04-14 04:46:42 +03:00
|
|
|
then
|
2022-10-20 20:26:36 +03:00
|
|
|
echo "Register capture test [Skipped missing event]"
|
2022-05-05 21:25:05 +03:00
|
|
|
if [ $err -ne 1 ]
|
|
|
|
then
|
|
|
|
err=2
|
|
|
|
fi
|
2022-04-14 04:46:42 +03:00
|
|
|
return
|
|
|
|
fi
|
2022-10-20 20:26:37 +03:00
|
|
|
if ! perf record --intr-regs=\? 2>&1 | grep -q 'available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10 R11 R12 R13 R14 R15'
|
2022-04-14 04:46:42 +03:00
|
|
|
then
|
|
|
|
echo "Register capture test [Skipped missing registers]"
|
|
|
|
return
|
|
|
|
fi
|
2022-09-27 08:15:13 +03:00
|
|
|
if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call:p \
|
2022-10-20 20:26:38 +03:00
|
|
|
-c 1000 --per-thread ${testprog} 2> /dev/null \
|
2022-04-14 04:46:42 +03:00
|
|
|
| perf script -F ip,sym,iregs -i - 2> /dev/null \
|
2022-10-20 20:26:37 +03:00
|
|
|
| grep -q "DI:"
|
2022-04-14 04:46:42 +03:00
|
|
|
then
|
|
|
|
echo "Register capture test [Failed missing output]"
|
|
|
|
err=1
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
echo "Register capture test [Success]"
|
|
|
|
}
|
|
|
|
|
2022-10-20 20:26:38 +03:00
|
|
|
build_test_program
|
|
|
|
|
2022-04-14 04:46:42 +03:00
|
|
|
test_per_thread
|
|
|
|
test_register_capture
|
2022-05-05 21:25:05 +03:00
|
|
|
|
|
|
|
cleanup
|
2022-04-14 04:46:42 +03:00
|
|
|
exit $err
|