162306a36Sopenharmony_ci#!/bin/sh 262306a36Sopenharmony_ci# kernel lock contention analysis test 362306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciset -e 662306a36Sopenharmony_ci 762306a36Sopenharmony_cierr=0 862306a36Sopenharmony_ciperfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) 962306a36Sopenharmony_ciresult=$(mktemp /tmp/__perf_test.result.XXXXX) 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cicleanup() { 1262306a36Sopenharmony_ci rm -f ${perfdata} 1362306a36Sopenharmony_ci rm -f ${result} 1462306a36Sopenharmony_ci trap - EXIT TERM INT 1562306a36Sopenharmony_ci} 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_citrap_cleanup() { 1862306a36Sopenharmony_ci cleanup 1962306a36Sopenharmony_ci exit ${err} 2062306a36Sopenharmony_ci} 2162306a36Sopenharmony_citrap trap_cleanup EXIT TERM INT 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cicheck() { 2462306a36Sopenharmony_ci if [ "$(id -u)" != 0 ]; then 2562306a36Sopenharmony_ci echo "[Skip] No root permission" 2662306a36Sopenharmony_ci err=2 2762306a36Sopenharmony_ci exit 2862306a36Sopenharmony_ci fi 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci if ! perf list | grep -q lock:contention_begin; then 3162306a36Sopenharmony_ci echo "[Skip] No lock contention tracepoints" 3262306a36Sopenharmony_ci err=2 3362306a36Sopenharmony_ci exit 3462306a36Sopenharmony_ci fi 3562306a36Sopenharmony_ci} 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_citest_record() 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci echo "Testing perf lock record and perf lock contention" 4062306a36Sopenharmony_ci perf lock record -o ${perfdata} -- perf bench sched messaging > /dev/null 2>&1 4162306a36Sopenharmony_ci # the output goes to the stderr and we expect only 1 output (-E 1) 4262306a36Sopenharmony_ci perf lock contention -i ${perfdata} -E 1 -q 2> ${result} 4362306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 4462306a36Sopenharmony_ci echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 4562306a36Sopenharmony_ci err=1 4662306a36Sopenharmony_ci exit 4762306a36Sopenharmony_ci fi 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_citest_bpf() 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci echo "Testing perf lock contention --use-bpf" 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 5562306a36Sopenharmony_ci echo "[Skip] No BPF support" 5662306a36Sopenharmony_ci return 5762306a36Sopenharmony_ci fi 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci # the perf lock contention output goes to the stderr 6062306a36Sopenharmony_ci perf lock con -a -b -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 6162306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 6262306a36Sopenharmony_ci echo "[Fail] BPF result count is not 1:" "$(cat "${result}" | wc -l)" 6362306a36Sopenharmony_ci err=1 6462306a36Sopenharmony_ci exit 6562306a36Sopenharmony_ci fi 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_citest_record_concurrent() 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci echo "Testing perf lock record and perf lock contention at the same time" 7162306a36Sopenharmony_ci perf lock record -o- -- perf bench sched messaging 2> /dev/null | \ 7262306a36Sopenharmony_ci perf lock contention -i- -E 1 -q 2> ${result} 7362306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 7462306a36Sopenharmony_ci echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 7562306a36Sopenharmony_ci err=1 7662306a36Sopenharmony_ci exit 7762306a36Sopenharmony_ci fi 7862306a36Sopenharmony_ci} 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_citest_aggr_task() 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci echo "Testing perf lock contention --threads" 8362306a36Sopenharmony_ci perf lock contention -i ${perfdata} -t -E 1 -q 2> ${result} 8462306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 8562306a36Sopenharmony_ci echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 8662306a36Sopenharmony_ci err=1 8762306a36Sopenharmony_ci exit 8862306a36Sopenharmony_ci fi 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 9162306a36Sopenharmony_ci return 9262306a36Sopenharmony_ci fi 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci # the perf lock contention output goes to the stderr 9562306a36Sopenharmony_ci perf lock con -a -b -t -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 9662306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 9762306a36Sopenharmony_ci echo "[Fail] BPF result count is not 1:" "$(cat "${result}" | wc -l)" 9862306a36Sopenharmony_ci err=1 9962306a36Sopenharmony_ci exit 10062306a36Sopenharmony_ci fi 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_citest_aggr_addr() 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci echo "Testing perf lock contention --lock-addr" 10662306a36Sopenharmony_ci perf lock contention -i ${perfdata} -l -E 1 -q 2> ${result} 10762306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 10862306a36Sopenharmony_ci echo "[Fail] Recorded result count is not 1:" "$(cat "${result}" | wc -l)" 10962306a36Sopenharmony_ci err=1 11062306a36Sopenharmony_ci exit 11162306a36Sopenharmony_ci fi 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 11462306a36Sopenharmony_ci return 11562306a36Sopenharmony_ci fi 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci # the perf lock contention output goes to the stderr 11862306a36Sopenharmony_ci perf lock con -a -b -l -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 11962306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 12062306a36Sopenharmony_ci echo "[Fail] BPF result count is not 1:" "$(cat "${result}" | wc -l)" 12162306a36Sopenharmony_ci err=1 12262306a36Sopenharmony_ci exit 12362306a36Sopenharmony_ci fi 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_citest_type_filter() 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci echo "Testing perf lock contention --type-filter (w/ spinlock)" 12962306a36Sopenharmony_ci perf lock contention -i ${perfdata} -Y spinlock -q 2> ${result} 13062306a36Sopenharmony_ci if [ "$(grep -c -v spinlock "${result}")" != "0" ]; then 13162306a36Sopenharmony_ci echo "[Fail] Recorded result should not have non-spinlocks:" "$(cat "${result}")" 13262306a36Sopenharmony_ci err=1 13362306a36Sopenharmony_ci exit 13462306a36Sopenharmony_ci fi 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 13762306a36Sopenharmony_ci return 13862306a36Sopenharmony_ci fi 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci perf lock con -a -b -Y spinlock -q -- perf bench sched messaging > /dev/null 2> ${result} 14162306a36Sopenharmony_ci if [ "$(grep -c -v spinlock "${result}")" != "0" ]; then 14262306a36Sopenharmony_ci echo "[Fail] BPF result should not have non-spinlocks:" "$(cat "${result}")" 14362306a36Sopenharmony_ci err=1 14462306a36Sopenharmony_ci exit 14562306a36Sopenharmony_ci fi 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_citest_lock_filter() 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci echo "Testing perf lock contention --lock-filter (w/ tasklist_lock)" 15162306a36Sopenharmony_ci perf lock contention -i ${perfdata} -l -q 2> ${result} 15262306a36Sopenharmony_ci if [ "$(grep -c tasklist_lock "${result}")" != "1" ]; then 15362306a36Sopenharmony_ci echo "[Skip] Could not find 'tasklist_lock'" 15462306a36Sopenharmony_ci return 15562306a36Sopenharmony_ci fi 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci perf lock contention -i ${perfdata} -L tasklist_lock -q 2> ${result} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci # find out the type of tasklist_lock 16062306a36Sopenharmony_ci test_lock_filter_type=$(head -1 "${result}" | awk '{ print $8 }' | sed -e 's/:.*//') 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci if [ "$(grep -c -v "${test_lock_filter_type}" "${result}")" != "0" ]; then 16362306a36Sopenharmony_ci echo "[Fail] Recorded result should not have non-${test_lock_filter_type} locks:" "$(cat "${result}")" 16462306a36Sopenharmony_ci err=1 16562306a36Sopenharmony_ci exit 16662306a36Sopenharmony_ci fi 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 16962306a36Sopenharmony_ci return 17062306a36Sopenharmony_ci fi 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci perf lock con -a -b -L tasklist_lock -q -- perf bench sched messaging > /dev/null 2> ${result} 17362306a36Sopenharmony_ci if [ "$(grep -c -v "${test_lock_filter_type}" "${result}")" != "0" ]; then 17462306a36Sopenharmony_ci echo "[Fail] BPF result should not have non-${test_lock_filter_type} locks:" "$(cat "${result}")" 17562306a36Sopenharmony_ci err=1 17662306a36Sopenharmony_ci exit 17762306a36Sopenharmony_ci fi 17862306a36Sopenharmony_ci} 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_citest_stack_filter() 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci echo "Testing perf lock contention --callstack-filter (w/ unix_stream)" 18362306a36Sopenharmony_ci perf lock contention -i ${perfdata} -v -q 2> ${result} 18462306a36Sopenharmony_ci if [ "$(grep -c unix_stream "${result}")" = "0" ]; then 18562306a36Sopenharmony_ci echo "[Skip] Could not find 'unix_stream'" 18662306a36Sopenharmony_ci return 18762306a36Sopenharmony_ci fi 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci perf lock contention -i ${perfdata} -E 1 -S unix_stream -q 2> ${result} 19062306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 19162306a36Sopenharmony_ci echo "[Fail] Recorded result should have a lock from unix_stream:" "$(cat "${result}")" 19262306a36Sopenharmony_ci err=1 19362306a36Sopenharmony_ci exit 19462306a36Sopenharmony_ci fi 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 19762306a36Sopenharmony_ci return 19862306a36Sopenharmony_ci fi 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci perf lock con -a -b -S unix_stream -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 20162306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 20262306a36Sopenharmony_ci echo "[Fail] BPF result should have a lock from unix_stream:" "$(cat "${result}")" 20362306a36Sopenharmony_ci err=1 20462306a36Sopenharmony_ci exit 20562306a36Sopenharmony_ci fi 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_citest_aggr_task_stack_filter() 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci echo "Testing perf lock contention --callstack-filter with task aggregation" 21162306a36Sopenharmony_ci perf lock contention -i ${perfdata} -v -q 2> ${result} 21262306a36Sopenharmony_ci if [ "$(grep -c unix_stream "${result}")" = "0" ]; then 21362306a36Sopenharmony_ci echo "[Skip] Could not find 'unix_stream'" 21462306a36Sopenharmony_ci return 21562306a36Sopenharmony_ci fi 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci perf lock contention -i ${perfdata} -t -E 1 -S unix_stream -q 2> ${result} 21862306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 21962306a36Sopenharmony_ci echo "[Fail] Recorded result should have a task from unix_stream:" "$(cat "${result}")" 22062306a36Sopenharmony_ci err=1 22162306a36Sopenharmony_ci exit 22262306a36Sopenharmony_ci fi 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 22562306a36Sopenharmony_ci return 22662306a36Sopenharmony_ci fi 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci perf lock con -a -b -t -S unix_stream -E 1 -q -- perf bench sched messaging > /dev/null 2> ${result} 22962306a36Sopenharmony_ci if [ "$(cat "${result}" | wc -l)" != "1" ]; then 23062306a36Sopenharmony_ci echo "[Fail] BPF result should have a task from unix_stream:" "$(cat "${result}")" 23162306a36Sopenharmony_ci err=1 23262306a36Sopenharmony_ci exit 23362306a36Sopenharmony_ci fi 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_citest_csv_output() 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci echo "Testing perf lock contention CSV output" 23962306a36Sopenharmony_ci perf lock contention -i ${perfdata} -E 1 -x , --output ${result} 24062306a36Sopenharmony_ci # count the number of commas in the header 24162306a36Sopenharmony_ci # it should have 5: contended, total-wait, max-wait, avg-wait, type, caller 24262306a36Sopenharmony_ci header=$(grep "# output:" ${result} | tr -d -c , | wc -c) 24362306a36Sopenharmony_ci if [ "${header}" != "5" ]; then 24462306a36Sopenharmony_ci echo "[Fail] Recorded result does not have enough output columns: ${header} != 5" 24562306a36Sopenharmony_ci err=1 24662306a36Sopenharmony_ci exit 24762306a36Sopenharmony_ci fi 24862306a36Sopenharmony_ci # count the number of commas in the output 24962306a36Sopenharmony_ci output=$(grep -v "^#" ${result} | tr -d -c , | wc -c) 25062306a36Sopenharmony_ci if [ "${header}" != "${output}" ]; then 25162306a36Sopenharmony_ci echo "[Fail] Recorded result does not match the number of commas: ${header} != ${output}" 25262306a36Sopenharmony_ci err=1 25362306a36Sopenharmony_ci exit 25462306a36Sopenharmony_ci fi 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if ! perf lock con -b true > /dev/null 2>&1 ; then 25762306a36Sopenharmony_ci echo "[Skip] No BPF support" 25862306a36Sopenharmony_ci return 25962306a36Sopenharmony_ci fi 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci # the perf lock contention output goes to the stderr 26262306a36Sopenharmony_ci perf lock con -a -b -E 1 -x , --output ${result} -- perf bench sched messaging > /dev/null 2>&1 26362306a36Sopenharmony_ci output=$(grep -v "^#" ${result} | tr -d -c , | wc -c) 26462306a36Sopenharmony_ci if [ "${header}" != "${output}" ]; then 26562306a36Sopenharmony_ci echo "[Fail] BPF result does not match the number of commas: ${header} != ${output}" 26662306a36Sopenharmony_ci err=1 26762306a36Sopenharmony_ci exit 26862306a36Sopenharmony_ci fi 26962306a36Sopenharmony_ci} 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cicheck 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_citest_record 27462306a36Sopenharmony_citest_bpf 27562306a36Sopenharmony_citest_record_concurrent 27662306a36Sopenharmony_citest_aggr_task 27762306a36Sopenharmony_citest_aggr_addr 27862306a36Sopenharmony_citest_type_filter 27962306a36Sopenharmony_citest_lock_filter 28062306a36Sopenharmony_citest_stack_filter 28162306a36Sopenharmony_citest_aggr_task_stack_filter 28262306a36Sopenharmony_citest_csv_output 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ciexit ${err} 285