1831d06c8SNamhyung Kim#!/bin/bash 2831d06c8SNamhyung Kim# perf record offcpu profiling tests (exclusive) 3831d06c8SNamhyung Kim# SPDX-License-Identifier: GPL-2.0 4831d06c8SNamhyung Kim 5831d06c8SNamhyung Kimset -e 6831d06c8SNamhyung Kim 7831d06c8SNamhyung Kimerr=0 8831d06c8SNamhyung Kimperfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 9831d06c8SNamhyung Kim 10831d06c8SNamhyung Kimts=$(printf "%u" $((~0 << 32))) # OFF_CPU_TIMESTAMP 11831d06c8SNamhyung Kimdummy_timestamp=${ts%???} # remove the last 3 digits to match perf script 12831d06c8SNamhyung Kim 13a225c304SKajol Jaincleanup() { 14831d06c8SNamhyung Kim rm -f ${perfdata} 15831d06c8SNamhyung Kim rm -f ${perfdata}.old 16831d06c8SNamhyung Kim trap - EXIT TERM INT 17831d06c8SNamhyung Kim} 18831d06c8SNamhyung Kim 19831d06c8SNamhyung Kimtrap_cleanup() { 20a225c304SKajol Jain cleanup 21831d06c8SNamhyung Kim exit 1 22ade1d030SNamhyung Kim} 23ade1d030SNamhyung Kimtrap trap_cleanup EXIT TERM INT 24ade1d030SNamhyung Kim 25a225c304SKajol Jaintest_above_thresh="Threshold test (above threshold)" 26831d06c8SNamhyung Kimtest_below_thresh="Threshold test (below threshold)" 27ade1d030SNamhyung Kim 28831d06c8SNamhyung Kimtest_offcpu_priv() { 29831d06c8SNamhyung Kim echo "Checking off-cpu privilege" 30831d06c8SNamhyung Kim 31b4f48f34SIan Rogers if [ "$(id -u)" != 0 ] 32831d06c8SNamhyung Kim then 33ade1d030SNamhyung Kim echo "off-cpu test [Skipped permission]" 34831d06c8SNamhyung Kim err=2 35831d06c8SNamhyung Kim return 36831d06c8SNamhyung Kim fi 37ade1d030SNamhyung Kim if perf version --build-options 2>&1 | grep HAVE_BPF_SKEL | grep -q OFF 38ade1d030SNamhyung Kim then 39ade1d030SNamhyung Kim echo "off-cpu test [Skipped missing BPF support]" 40ade1d030SNamhyung Kim err=2 41ade1d030SNamhyung Kim return 42831d06c8SNamhyung Kim fi 43831d06c8SNamhyung Kim} 44831d06c8SNamhyung Kim 45831d06c8SNamhyung Kimtest_offcpu_basic() { 46831d06c8SNamhyung Kim echo "Basic off-cpu test" 47831d06c8SNamhyung Kim 48831d06c8SNamhyung Kim if ! perf record --off-cpu -e dummy -o ${perfdata} sleep 1 2> /dev/null 49831d06c8SNamhyung Kim then 50ade1d030SNamhyung Kim echo "Basic off-cpu test [Failed record]" 51831d06c8SNamhyung Kim err=1 52831d06c8SNamhyung Kim return 53831d06c8SNamhyung Kim fi 54818448e9STiezhu Yang if ! perf evlist -i ${perfdata} | grep -q "offcpu-time" 55831d06c8SNamhyung Kim then 56831d06c8SNamhyung Kim echo "Basic off-cpu test [Failed no event]" 57831d06c8SNamhyung Kim err=1 58831d06c8SNamhyung Kim return 59831d06c8SNamhyung Kim fi 60831d06c8SNamhyung Kim if ! perf report -i ${perfdata} -q --percent-limit=90 | grep -E -q sleep 61831d06c8SNamhyung Kim then 62831d06c8SNamhyung Kim echo "Basic off-cpu test [Failed missing output]" 63ade1d030SNamhyung Kim err=1 64ade1d030SNamhyung Kim return 65ade1d030SNamhyung Kim fi 66ade1d030SNamhyung Kim echo "Basic off-cpu test [Success]" 67ade1d030SNamhyung Kim} 689835b742SPatrice Duroux 69ade1d030SNamhyung Kimtest_offcpu_child() { 70ade1d030SNamhyung Kim echo "Child task off-cpu test" 71ade1d030SNamhyung Kim 72ade1d030SNamhyung Kim # perf bench sched messaging creates 400 processes 73ade1d030SNamhyung Kim if ! perf record --off-cpu -e dummy -o ${perfdata} -- \ 74ade1d030SNamhyung Kim perf bench sched messaging -g 10 > /dev/null 2>&1 75ade1d030SNamhyung Kim then 76ade1d030SNamhyung Kim echo "Child task off-cpu test [Failed record]" 77ade1d030SNamhyung Kim err=1 78ade1d030SNamhyung Kim return 79ade1d030SNamhyung Kim fi 80*b861fd7eSThomas Richter if ! perf evlist -i ${perfdata} | grep -q "offcpu-time" 81ade1d030SNamhyung Kim then 82*b861fd7eSThomas Richter echo "Child task off-cpu test [Failed no event]" 83ade1d030SNamhyung Kim err=1 84ade1d030SNamhyung Kim return 85ade1d030SNamhyung Kim fi 86ade1d030SNamhyung Kim # each process waits at least for poll, so it should be more than 400 events 87ade1d030SNamhyung Kim if ! perf report -i ${perfdata} -s comm -q -n -t ';' --percent-limit=90 | \ 88ade1d030SNamhyung Kim awk -F ";" '{ if (NF > 3 && int($3) < 400) exit 1; }' 89ade1d030SNamhyung Kim then 90ade1d030SNamhyung Kim echo "Child task off-cpu test [Failed invalid output]" 91ade1d030SNamhyung Kim err=1 92ade1d030SNamhyung Kim return 93ade1d030SNamhyung Kim fi 94ade1d030SNamhyung Kim echo "Child task off-cpu test [Success]" 95ade1d030SNamhyung Kim} 96ade1d030SNamhyung Kim 97ade1d030SNamhyung Kim# task blocks longer than the --off-cpu-thresh, perf should collect a direct sample 98ade1d030SNamhyung Kimtest_offcpu_above_thresh() { 99ade1d030SNamhyung Kim echo "${test_above_thresh}" 100ade1d030SNamhyung Kim 101831d06c8SNamhyung Kim # collect direct off-cpu samples for tasks blocked for more than 999ms 102831d06c8SNamhyung Kim if ! perf record -e dummy --off-cpu --off-cpu-thresh 999 -o ${perfdata} -- sleep 1 2> /dev/null 103831d06c8SNamhyung Kim then 104 echo "${test_above_thresh} [Failed record]" 105 err=1 106 return 107 fi 108 # direct sample's timestamp should be lower than the dummy_timestamp of the at-the-end sample 109 # check if a direct sample exists 110 if ! perf script --time "0, ${dummy_timestamp}" -i ${perfdata} -F event | grep -q "offcpu-time" 111 then 112 echo "${test_above_thresh} [Failed missing direct samples]" 113 err=1 114 return 115 fi 116 # there should only be one direct sample, and its period should be higher than off-cpu-thresh 117 if ! perf script --time "0, ${dummy_timestamp}" -i ${perfdata} -F period | \ 118 awk '{ if (int($1) > 999000000) exit 0; else exit 1; }' 119 then 120 echo "${test_above_thresh} [Failed off-cpu time too short]" 121 err=1 122 return 123 fi 124 echo "${test_above_thresh} [Success]" 125} 126 127# task blocks shorter than the --off-cpu-thresh, perf should collect an at-the-end sample 128test_offcpu_below_thresh() { 129 echo "${test_below_thresh}" 130 131 # collect direct off-cpu samples for tasks blocked for more than 1.2s 132 if ! perf record -e dummy --off-cpu --off-cpu-thresh 1200 -o ${perfdata} -- sleep 1 2> /dev/null 133 then 134 echo "${test_below_thresh} [Failed record]" 135 err=1 136 return 137 fi 138 # see if there's an at-the-end sample 139 if ! perf script --time "${dummy_timestamp}," -i ${perfdata} -F event | grep -q 'offcpu-time' 140 then 141 echo "${test_below_thresh} [Failed at-the-end samples cannot be found]" 142 err=1 143 return 144 fi 145 # plus there shouldn't be any direct samples 146 if perf script --time "0, ${dummy_timestamp}" -i ${perfdata} -F event | grep -q 'offcpu-time' 147 then 148 echo "${test_below_thresh} [Failed direct samples are found when they shouldn't be]" 149 err=1 150 return 151 fi 152 echo "${test_below_thresh} [Success]" 153} 154 155test_offcpu_priv 156 157if [ $err = 0 ]; then 158 test_offcpu_basic 159fi 160 161if [ $err = 0 ]; then 162 test_offcpu_child 163fi 164 165if [ $err = 0 ]; then 166 test_offcpu_above_thresh 167fi 168 169if [ $err = 0 ]; then 170 test_offcpu_below_thresh 171fi 172 173cleanup 174exit $err 175