1#!/bin/sh 2# perf record tests 3# SPDX-License-Identifier: GPL-2.0 4 5set -e 6 7shelldir=$(dirname "$0") 8. "${shelldir}"/lib/waiting.sh 9 10err=0 11perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 12testprog=$(mktemp /tmp/__perf_test.prog.XXXXXX) 13testsym="test_loop" 14 15cleanup() { 16 rm -f "${perfdata}" 17 rm -f "${perfdata}".old 18 19 if [ "${testprog}" != "true" ]; then 20 rm -f "${testprog}" 21 fi 22 23 trap - EXIT TERM INT 24} 25 26trap_cleanup() { 27 cleanup 28 exit 1 29} 30trap trap_cleanup EXIT TERM INT 31 32build_test_program() { 33 if ! [ -x "$(command -v cc)" ]; then 34 # No CC found. Fall back to 'true' 35 testprog=true 36 testsym=true 37 return 38 fi 39 40 echo "Build a test program" 41 cat <<EOF | cc -o ${testprog} -xc - -pthread 42#include <stdio.h> 43#include <stdlib.h> 44#include <pthread.h> 45 46void test_loop(void) { 47 volatile int count = 1000000; 48 49 while (count--) 50 continue; 51} 52 53void *thfunc(void *arg) { 54 int forever = *(int *)arg; 55 56 do { 57 test_loop(); 58 } while (forever); 59 60 return NULL; 61} 62 63int main(int argc, char *argv[]) { 64 pthread_t th; 65 int forever = 0; 66 67 if (argc > 1) 68 forever = atoi(argv[1]); 69 70 pthread_create(&th, NULL, thfunc, &forever); 71 test_loop(); 72 pthread_join(th, NULL); 73 74 return 0; 75} 76EOF 77} 78 79test_per_thread() { 80 echo "Basic --per-thread mode test" 81 if ! perf record -o /dev/null --quiet ${testprog} 2> /dev/null 82 then 83 echo "Per-thread record [Skipped event not supported]" 84 if [ $err -ne 1 ] 85 then 86 err=2 87 fi 88 return 89 fi 90 if ! perf record --per-thread -o "${perfdata}" ${testprog} 2> /dev/null 91 then 92 echo "Per-thread record [Failed record]" 93 err=1 94 return 95 fi 96 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 97 then 98 echo "Per-thread record [Failed missing output]" 99 err=1 100 return 101 fi 102 103 # run the test program in background (forever) 104 ${testprog} 1 & 105 TESTPID=$! 106 107 rm -f "${perfdata}" 108 109 wait_for_threads ${TESTPID} 2 110 perf record -p "${TESTPID}" --per-thread -o "${perfdata}" sleep 1 2> /dev/null 111 kill ${TESTPID} 112 113 if [ ! -e "${perfdata}" ] 114 then 115 echo "Per-thread record [Failed record -p]" 116 err=1 117 return 118 fi 119 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 120 then 121 echo "Per-thread record [Failed -p missing output]" 122 err=1 123 return 124 fi 125 126 echo "Basic --per-thread mode test [Success]" 127} 128 129test_register_capture() { 130 echo "Register capture test" 131 if ! perf list | grep -q 'br_inst_retired.near_call' 132 then 133 echo "Register capture test [Skipped missing event]" 134 if [ $err -ne 1 ] 135 then 136 err=2 137 fi 138 return 139 fi 140 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' 141 then 142 echo "Register capture test [Skipped missing registers]" 143 return 144 fi 145 if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call:p \ 146 -c 1000 --per-thread ${testprog} 2> /dev/null \ 147 | perf script -F ip,sym,iregs -i - 2> /dev/null \ 148 | grep -q "DI:" 149 then 150 echo "Register capture test [Failed missing output]" 151 err=1 152 return 153 fi 154 echo "Register capture test [Success]" 155} 156 157test_system_wide() { 158 echo "Basic --system-wide mode test" 159 if ! perf record -aB --synth=no -o "${perfdata}" ${testprog} 2> /dev/null 160 then 161 echo "System-wide record [Skipped not supported]" 162 if [ $err -ne 1 ] 163 then 164 err=2 165 fi 166 return 167 fi 168 if ! perf report -i "${perfdata}" -q | grep -q "${testsym}" 169 then 170 echo "System-wide record [Failed missing output]" 171 err=1 172 return 173 fi 174 echo "Basic --system-wide mode test [Success]" 175} 176 177build_test_program 178 179test_per_thread 180test_register_capture 181test_system_wide 182 183cleanup 184exit $err 185