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