1#!/bin/sh 2# kernel lock contention analysis test 3# SPDX-License-Identifier: GPL-2.0 4 5set -e 6 7err=0 8perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 9result=$(mktemp /tmp/__perf_test.result.XXXXX) 10 11cleanup() { 12 rm -f ${perfdata} 13 rm -f ${result} 14 trap - exit term int 15} 16 17trap_cleanup() { 18 cleanup 19 exit ${err} 20} 21trap trap_cleanup exit term int 22 23check() { 24 if [ `id -u` != 0 ]; then 25 echo "[Skip] No root permission" 26 err=2 27 exit 28 fi 29 30 if ! perf list | grep -q lock:contention_begin; then 31 echo "[Skip] No lock contention tracepoints" 32 err=2 33 exit 34 fi 35} 36 37test_record() 38{ 39 echo "Testing perf lock record and perf lock contention" 40 perf lock record -o ${perfdata} -- perf bench sched messaging > /dev/null 2>&1 41 # the output goes to the stderr and we expect only 1 output (-E 1) 42 perf lock contention -i ${perfdata} -E 1 -q 2> ${result} 43 if [ $(cat "${result}" | wc -l) != "1" ]; then 44 echo "[Fail] Recorded result count is not 1:" $(cat "${result}" | wc -l) 45 err=1 46 exit 47 fi 48} 49 50test_bpf() 51{ 52 echo "Testing perf lock contention --use-bpf" 53 54 if ! perf lock con -b true > /dev/null 2>&1 ; then 55 echo "[Skip] No BPF support" 56 return 57 fi 58 59 # the perf lock contention output goes to the stderr 60 perf lock con -a -b -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 61 if [ $(cat "${result}" | wc -l) != "1" ]; then 62 echo "[Fail] BPF result count is not 1:" $(cat "${result}" | wc -l) 63 err=1 64 exit 65 fi 66} 67 68test_record_concurrent() 69{ 70 echo "Testing perf lock record and perf lock contention at the same time" 71 perf lock record -o- -- perf bench sched messaging 2> /dev/null | \ 72 perf lock contention -i- -E 1 -q 2> ${result} 73 if [ $(cat "${result}" | wc -l) != "1" ]; then 74 echo "[Fail] Recorded result count is not 1:" $(cat "${result}" | wc -l) 75 err=1 76 exit 77 fi 78} 79 80test_aggr_task() 81{ 82 echo "Testing perf lock contention --threads" 83 perf lock contention -i ${perfdata} -t -E 1 -q 2> ${result} 84 if [ $(cat "${result}" | wc -l) != "1" ]; then 85 echo "[Fail] Recorded result count is not 1:" $(cat "${result}" | wc -l) 86 err=1 87 exit 88 fi 89 90 if ! perf lock con -b true > /dev/null 2>&1 ; then 91 return 92 fi 93 94 # the perf lock contention output goes to the stderr 95 perf lock con -a -b -t -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 96 if [ $(cat "${result}" | wc -l) != "1" ]; then 97 echo "[Fail] BPF result count is not 1:" $(cat "${result}" | wc -l) 98 err=1 99 exit 100 fi 101} 102 103test_aggr_addr() 104{ 105 echo "Testing perf lock contention --lock-addr" 106 perf lock contention -i ${perfdata} -l -E 1 -q 2> ${result} 107 if [ $(cat "${result}" | wc -l) != "1" ]; then 108 echo "[Fail] Recorded result count is not 1:" $(cat "${result}" | wc -l) 109 err=1 110 exit 111 fi 112 113 if ! perf lock con -b true > /dev/null 2>&1 ; then 114 return 115 fi 116 117 # the perf lock contention output goes to the stderr 118 perf lock con -a -b -l -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 119 if [ $(cat "${result}" | wc -l) != "1" ]; then 120 echo "[Fail] BPF result count is not 1:" $(cat "${result}" | wc -l) 121 err=1 122 exit 123 fi 124} 125 126test_type_filter() 127{ 128 echo "Testing perf lock contention --type-filter (w/ spinlock)" 129 perf lock contention -i ${perfdata} -Y spinlock -q 2> ${result} 130 if [ $(grep -c -v spinlock "${result}") != "0" ]; then 131 echo "[Fail] Recorded should not have non-spinlocks:" $(cat "${result}") 132 err=1 133 exit 134 fi 135 136 if ! perf lock con -b true > /dev/null 2>&1 ; then 137 return 138 fi 139 140 perf lock con -a -b -Y spinlock -q -- perf bench sched messaging > /dev/null 2> ${result} 141 if [ $(grep -c -v spinlock "${result}") != "0" ]; then 142 echo "[Fail] Recorded should not have non-spinlocks:" $(cat "${result}") 143 err=1 144 exit 145 fi 146} 147 148test_lock_filter() 149{ 150 echo "Testing perf lock contention --lock-filter (w/ tasklist_lock)" 151 perf lock contention -i ${perfdata} -l -q 2> ${result} 152 if [ $(grep -c tasklist_lock "${result}") != "1" ]; then 153 echo "[Skip] Could not find 'tasklist_lock'" 154 return 155 fi 156 157 perf lock contention -i ${perfdata} -L tasklist_lock -q 2> ${result} 158 159 # find out the type of tasklist_lock 160 local type=$(head -1 "${result}" | awk '{ print $8 }' | sed -e 's/:.*//') 161 162 if [ $(grep -c -v "${type}" "${result}") != "0" ]; then 163 echo "[Fail] Recorded should not have non-${type} locks:" $(cat "${result}") 164 err=1 165 exit 166 fi 167 168 if ! perf lock con -b true > /dev/null 2>&1 ; then 169 return 170 fi 171 172 perf lock con -a -b -L tasklist_lock -q -- perf bench sched messaging > /dev/null 2> ${result} 173 if [ $(grep -c -v "${type}" "${result}") != "0" ]; then 174 echo "[Fail] Recorded should not have non-${type} locks:" $(cat "${result}") 175 err=1 176 exit 177 fi 178} 179 180check 181 182test_record 183test_bpf 184test_record_concurrent 185test_aggr_task 186test_aggr_addr 187test_type_filter 188test_lock_filter 189 190exit ${err} 191