1ec685de2SNamhyung Kim#!/bin/sh 2ec685de2SNamhyung Kim# kernel lock contention analysis test 3ec685de2SNamhyung Kim# SPDX-License-Identifier: GPL-2.0 4ec685de2SNamhyung Kim 5ec685de2SNamhyung Kimset -e 6ec685de2SNamhyung Kim 7ec685de2SNamhyung Kimerr=0 8ec685de2SNamhyung Kimperfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 9ec685de2SNamhyung Kimresult=$(mktemp /tmp/__perf_test.result.XXXXX) 10ec685de2SNamhyung Kim 11ec685de2SNamhyung Kimcleanup() { 12ec685de2SNamhyung Kim rm -f ${perfdata} 13ec685de2SNamhyung Kim rm -f ${result} 14fa33cbe2SAbhirup Deb trap - EXIT TERM INT 15ec685de2SNamhyung Kim} 16ec685de2SNamhyung Kim 17ec685de2SNamhyung Kimtrap_cleanup() { 18ec685de2SNamhyung Kim cleanup 19ec685de2SNamhyung Kim exit ${err} 20ec685de2SNamhyung Kim} 21fa33cbe2SAbhirup Debtrap trap_cleanup EXIT TERM INT 22ec685de2SNamhyung Kim 23ec685de2SNamhyung Kimcheck() { 24*edf197cbSKajol Jain if [ "$(id -u)" != 0 ]; then 25ec685de2SNamhyung Kim echo "[Skip] No root permission" 26ec685de2SNamhyung Kim err=2 27ec685de2SNamhyung Kim exit 28ec685de2SNamhyung Kim fi 29ec685de2SNamhyung Kim 30ec685de2SNamhyung Kim if ! perf list | grep -q lock:contention_begin; then 31ec685de2SNamhyung Kim echo "[Skip] No lock contention tracepoints" 32ec685de2SNamhyung Kim err=2 33ec685de2SNamhyung Kim exit 34ec685de2SNamhyung Kim fi 35ec685de2SNamhyung Kim} 36ec685de2SNamhyung Kim 37ec685de2SNamhyung Kimtest_record() 38ec685de2SNamhyung Kim{ 39ec685de2SNamhyung Kim echo "Testing perf lock record and perf lock contention" 40ec685de2SNamhyung Kim perf lock record -o ${perfdata} -- perf bench sched messaging > /dev/null 2>&1 41ec685de2SNamhyung Kim # the output goes to the stderr and we expect only 1 output (-E 1) 42ec685de2SNamhyung Kim perf lock contention -i ${perfdata} -E 1 -q 2> ${result} 43fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 44fa33cbe2SAbhirup Deb echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 45ec685de2SNamhyung Kim err=1 46ec685de2SNamhyung Kim exit 47ec685de2SNamhyung Kim fi 48ec685de2SNamhyung Kim} 49ec685de2SNamhyung Kim 50ec685de2SNamhyung Kimtest_bpf() 51ec685de2SNamhyung Kim{ 52ec685de2SNamhyung Kim echo "Testing perf lock contention --use-bpf" 53ec685de2SNamhyung Kim 54ec685de2SNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 55ec685de2SNamhyung Kim echo "[Skip] No BPF support" 5630b331d2SNamhyung Kim return 57ec685de2SNamhyung Kim fi 58ec685de2SNamhyung Kim 59ec685de2SNamhyung Kim # the perf lock contention output goes to the stderr 60ec685de2SNamhyung Kim perf lock con -a -b -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 61fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 62fa33cbe2SAbhirup Deb echo "[Fail] BPF result count is not 1:" "$(cat "${result}" | wc -l)" 63ec685de2SNamhyung Kim err=1 64ec685de2SNamhyung Kim exit 65ec685de2SNamhyung Kim fi 66ec685de2SNamhyung Kim} 67ec685de2SNamhyung Kim 6830b331d2SNamhyung Kimtest_record_concurrent() 6930b331d2SNamhyung Kim{ 7030b331d2SNamhyung Kim echo "Testing perf lock record and perf lock contention at the same time" 7130b331d2SNamhyung Kim perf lock record -o- -- perf bench sched messaging 2> /dev/null | \ 7230b331d2SNamhyung Kim perf lock contention -i- -E 1 -q 2> ${result} 73fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 74fa33cbe2SAbhirup Deb echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 7530b331d2SNamhyung Kim err=1 7630b331d2SNamhyung Kim exit 7730b331d2SNamhyung Kim fi 7830b331d2SNamhyung Kim} 7930b331d2SNamhyung Kim 8022ddcb6bSNamhyung Kimtest_aggr_task() 8122ddcb6bSNamhyung Kim{ 8222ddcb6bSNamhyung Kim echo "Testing perf lock contention --threads" 8322ddcb6bSNamhyung Kim perf lock contention -i ${perfdata} -t -E 1 -q 2> ${result} 84fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 85fa33cbe2SAbhirup Deb echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 8622ddcb6bSNamhyung Kim err=1 8722ddcb6bSNamhyung Kim exit 8822ddcb6bSNamhyung Kim fi 8922ddcb6bSNamhyung Kim 9022ddcb6bSNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 9122ddcb6bSNamhyung Kim return 9222ddcb6bSNamhyung Kim fi 9322ddcb6bSNamhyung Kim 9422ddcb6bSNamhyung Kim # the perf lock contention output goes to the stderr 9522ddcb6bSNamhyung Kim perf lock con -a -b -t -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 96fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 97fa33cbe2SAbhirup Deb echo "[Fail] BPF result count is not 1:" "$(cat "${result}" | wc -l)" 9822ddcb6bSNamhyung Kim err=1 9922ddcb6bSNamhyung Kim exit 10022ddcb6bSNamhyung Kim fi 10122ddcb6bSNamhyung Kim} 10222ddcb6bSNamhyung Kim 10322ddcb6bSNamhyung Kimtest_aggr_addr() 10422ddcb6bSNamhyung Kim{ 10522ddcb6bSNamhyung Kim echo "Testing perf lock contention --lock-addr" 10622ddcb6bSNamhyung Kim perf lock contention -i ${perfdata} -l -E 1 -q 2> ${result} 107fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 108fa33cbe2SAbhirup Deb echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 10922ddcb6bSNamhyung Kim err=1 11022ddcb6bSNamhyung Kim exit 11122ddcb6bSNamhyung Kim fi 11222ddcb6bSNamhyung Kim 11322ddcb6bSNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 11422ddcb6bSNamhyung Kim return 11522ddcb6bSNamhyung Kim fi 11622ddcb6bSNamhyung Kim 11722ddcb6bSNamhyung Kim # the perf lock contention output goes to the stderr 118cb459c89SNamhyung Kim perf lock con -a -b -l -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 119fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 120fa33cbe2SAbhirup Deb echo "[Fail] BPF result count is not 1:" "$(cat "${result}" | wc -l)" 12122ddcb6bSNamhyung Kim err=1 12222ddcb6bSNamhyung Kim exit 12322ddcb6bSNamhyung Kim fi 12422ddcb6bSNamhyung Kim} 12522ddcb6bSNamhyung Kim 126cb459c89SNamhyung Kimtest_type_filter() 127cb459c89SNamhyung Kim{ 128cb459c89SNamhyung Kim echo "Testing perf lock contention --type-filter (w/ spinlock)" 129cb459c89SNamhyung Kim perf lock contention -i ${perfdata} -Y spinlock -q 2> ${result} 130fa33cbe2SAbhirup Deb if [ "$(grep -c -v spinlock "${result}")" != "0" ]; then 131fa33cbe2SAbhirup Deb echo "[Fail] Recorded result should not have non-spinlocks:" "$(cat "${result}")" 132cb459c89SNamhyung Kim err=1 133cb459c89SNamhyung Kim exit 134cb459c89SNamhyung Kim fi 135cb459c89SNamhyung Kim 136cb459c89SNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 137cb459c89SNamhyung Kim return 138cb459c89SNamhyung Kim fi 139cb459c89SNamhyung Kim 140cb459c89SNamhyung Kim perf lock con -a -b -Y spinlock -q -- perf bench sched messaging > /dev/null 2> ${result} 141fa33cbe2SAbhirup Deb if [ "$(grep -c -v spinlock "${result}")" != "0" ]; then 142fa33cbe2SAbhirup Deb echo "[Fail] BPF result should not have non-spinlocks:" "$(cat "${result}")" 143cb459c89SNamhyung Kim err=1 144cb459c89SNamhyung Kim exit 145cb459c89SNamhyung Kim fi 146cb459c89SNamhyung Kim} 147cb459c89SNamhyung Kim 148cb459c89SNamhyung Kimtest_lock_filter() 149cb459c89SNamhyung Kim{ 150cb459c89SNamhyung Kim echo "Testing perf lock contention --lock-filter (w/ tasklist_lock)" 151cb459c89SNamhyung Kim perf lock contention -i ${perfdata} -l -q 2> ${result} 152fa33cbe2SAbhirup Deb if [ "$(grep -c tasklist_lock "${result}")" != "1" ]; then 153cb459c89SNamhyung Kim echo "[Skip] Could not find 'tasklist_lock'" 154cb459c89SNamhyung Kim return 155cb459c89SNamhyung Kim fi 156cb459c89SNamhyung Kim 157cb459c89SNamhyung Kim perf lock contention -i ${perfdata} -L tasklist_lock -q 2> ${result} 158cb459c89SNamhyung Kim 159cb459c89SNamhyung Kim # find out the type of tasklist_lock 160*edf197cbSKajol Jain test_lock_filter_type=$(head -1 "${result}" | awk '{ print $8 }' | sed -e 's/:.*//') 161cb459c89SNamhyung Kim 162*edf197cbSKajol Jain if [ "$(grep -c -v "${test_lock_filter_type}" "${result}")" != "0" ]; then 163*edf197cbSKajol Jain echo "[Fail] Recorded result should not have non-${test_lock_filter_type} locks:" "$(cat "${result}")" 164cb459c89SNamhyung Kim err=1 165cb459c89SNamhyung Kim exit 166cb459c89SNamhyung Kim fi 167cb459c89SNamhyung Kim 168cb459c89SNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 169cb459c89SNamhyung Kim return 170cb459c89SNamhyung Kim fi 171cb459c89SNamhyung Kim 172cb459c89SNamhyung Kim perf lock con -a -b -L tasklist_lock -q -- perf bench sched messaging > /dev/null 2> ${result} 173*edf197cbSKajol Jain if [ "$(grep -c -v "${test_lock_filter_type}" "${result}")" != "0" ]; then 174*edf197cbSKajol Jain echo "[Fail] BPF result should not have non-${test_lock_filter_type} locks:" "$(cat "${result}")" 17579b7ca78SNamhyung Kim err=1 17679b7ca78SNamhyung Kim exit 17779b7ca78SNamhyung Kim fi 17879b7ca78SNamhyung Kim} 17979b7ca78SNamhyung Kim 18079b7ca78SNamhyung Kimtest_stack_filter() 18179b7ca78SNamhyung Kim{ 18279b7ca78SNamhyung Kim echo "Testing perf lock contention --callstack-filter (w/ unix_stream)" 18379b7ca78SNamhyung Kim perf lock contention -i ${perfdata} -v -q 2> ${result} 184fa33cbe2SAbhirup Deb if [ "$(grep -c unix_stream "${result}")" = "0" ]; then 18579b7ca78SNamhyung Kim echo "[Skip] Could not find 'unix_stream'" 18679b7ca78SNamhyung Kim return 18779b7ca78SNamhyung Kim fi 18879b7ca78SNamhyung Kim 18979b7ca78SNamhyung Kim perf lock contention -i ${perfdata} -E 1 -S unix_stream -q 2> ${result} 190fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 191fa33cbe2SAbhirup Deb echo "[Fail] Recorded result should have a lock from unix_stream:" "$(cat "${result}")" 19279b7ca78SNamhyung Kim err=1 19379b7ca78SNamhyung Kim exit 19479b7ca78SNamhyung Kim fi 19579b7ca78SNamhyung Kim 19679b7ca78SNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 19779b7ca78SNamhyung Kim return 19879b7ca78SNamhyung Kim fi 19979b7ca78SNamhyung Kim 20079b7ca78SNamhyung Kim perf lock con -a -b -S unix_stream -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 201fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 202fa33cbe2SAbhirup Deb echo "[Fail] BPF result should have a lock from unix_stream:" "$(cat "${result}")" 20379b7ca78SNamhyung Kim err=1 20479b7ca78SNamhyung Kim exit 20579b7ca78SNamhyung Kim fi 20679b7ca78SNamhyung Kim} 20779b7ca78SNamhyung Kim 20879b7ca78SNamhyung Kimtest_aggr_task_stack_filter() 20979b7ca78SNamhyung Kim{ 21079b7ca78SNamhyung Kim echo "Testing perf lock contention --callstack-filter with task aggregation" 21179b7ca78SNamhyung Kim perf lock contention -i ${perfdata} -v -q 2> ${result} 212fa33cbe2SAbhirup Deb if [ "$(grep -c unix_stream "${result}")" = "0" ]; then 21379b7ca78SNamhyung Kim echo "[Skip] Could not find 'unix_stream'" 21479b7ca78SNamhyung Kim return 21579b7ca78SNamhyung Kim fi 21679b7ca78SNamhyung Kim 21779b7ca78SNamhyung Kim perf lock contention -i ${perfdata} -t -E 1 -S unix_stream -q 2> ${result} 218fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 219fa33cbe2SAbhirup Deb echo "[Fail] Recorded result should have a task from unix_stream:" "$(cat "${result}")" 22079b7ca78SNamhyung Kim err=1 22179b7ca78SNamhyung Kim exit 22279b7ca78SNamhyung Kim fi 22379b7ca78SNamhyung Kim 22479b7ca78SNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 22579b7ca78SNamhyung Kim return 22679b7ca78SNamhyung Kim fi 22779b7ca78SNamhyung Kim 22879b7ca78SNamhyung Kim perf lock con -a -b -t -S unix_stream -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 229fa33cbe2SAbhirup Deb if [ "$(cat "${result}" | wc -l)" != "1" ]; then 230fa33cbe2SAbhirup Deb echo "[Fail] BPF result should have a task from unix_stream:" "$(cat "${result}")" 231cb459c89SNamhyung Kim err=1 232cb459c89SNamhyung Kim exit 233cb459c89SNamhyung Kim fi 234cb459c89SNamhyung Kim} 235cb459c89SNamhyung Kim 2362aefb4ccSNamhyung Kimtest_csv_output() 2372aefb4ccSNamhyung Kim{ 2382aefb4ccSNamhyung Kim echo "Testing perf lock contention CSV output" 2392aefb4ccSNamhyung Kim perf lock contention -i ${perfdata} -E 1 -x , --output ${result} 2402aefb4ccSNamhyung Kim # count the number of commas in the header 2412aefb4ccSNamhyung Kim # it should have 5: contended, total-wait, max-wait, avg-wait, type, caller 2422aefb4ccSNamhyung Kim header=$(grep "# output:" ${result} | tr -d -c , | wc -c) 2432aefb4ccSNamhyung Kim if [ "${header}" != "5" ]; then 2442aefb4ccSNamhyung Kim echo "[Fail] Recorded result does not have enough output columns: ${header} != 5" 2452aefb4ccSNamhyung Kim err=1 2462aefb4ccSNamhyung Kim exit 2472aefb4ccSNamhyung Kim fi 2482aefb4ccSNamhyung Kim # count the number of commas in the output 2492aefb4ccSNamhyung Kim output=$(grep -v "^#" ${result} | tr -d -c , | wc -c) 2502aefb4ccSNamhyung Kim if [ "${header}" != "${output}" ]; then 2512aefb4ccSNamhyung Kim echo "[Fail] Recorded result does not match the number of commas: ${header} != ${output}" 2522aefb4ccSNamhyung Kim err=1 2532aefb4ccSNamhyung Kim exit 2542aefb4ccSNamhyung Kim fi 2552aefb4ccSNamhyung Kim 2562aefb4ccSNamhyung Kim if ! perf lock con -b true > /dev/null 2>&1 ; then 2572aefb4ccSNamhyung Kim echo "[Skip] No BPF support" 2582aefb4ccSNamhyung Kim return 2592aefb4ccSNamhyung Kim fi 2602aefb4ccSNamhyung Kim 2612aefb4ccSNamhyung Kim # the perf lock contention output goes to the stderr 2622aefb4ccSNamhyung Kim perf lock con -a -b -E 1 -x , --output ${result} -- perf bench sched messaging > /dev/null 2>&1 2632aefb4ccSNamhyung Kim output=$(grep -v "^#" ${result} | tr -d -c , | wc -c) 2642aefb4ccSNamhyung Kim if [ "${header}" != "${output}" ]; then 2652aefb4ccSNamhyung Kim echo "[Fail] BPF result does not match the number of commas: ${header} != ${output}" 2662aefb4ccSNamhyung Kim err=1 2672aefb4ccSNamhyung Kim exit 2682aefb4ccSNamhyung Kim fi 2692aefb4ccSNamhyung Kim} 2702aefb4ccSNamhyung Kim 271ec685de2SNamhyung Kimcheck 272ec685de2SNamhyung Kim 273ec685de2SNamhyung Kimtest_record 274ec685de2SNamhyung Kimtest_bpf 27530b331d2SNamhyung Kimtest_record_concurrent 27622ddcb6bSNamhyung Kimtest_aggr_task 27722ddcb6bSNamhyung Kimtest_aggr_addr 278cb459c89SNamhyung Kimtest_type_filter 279cb459c89SNamhyung Kimtest_lock_filter 28079b7ca78SNamhyung Kimtest_stack_filter 28179b7ca78SNamhyung Kimtest_aggr_task_stack_filter 2822aefb4ccSNamhyung Kimtest_csv_output 283ec685de2SNamhyung Kim 284ec685de2SNamhyung Kimexit ${err} 285