xref: /linux/tools/testing/selftests/amd-pstate/run.sh (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# protect against multiple inclusion
5if [ $FILE_MAIN ]; then
6	return 0
7else
8	FILE_MAIN=DONE
9fi
10
11SCRIPTDIR=`dirname "$0"`
12TRACER=$SCRIPTDIR/../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py
13
14source $SCRIPTDIR/basic.sh
15source $SCRIPTDIR/tbench.sh
16source $SCRIPTDIR/gitsource.sh
17
18# amd-pstate-ut only run on x86/x86_64 AMD systems.
19ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/')
20VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}')
21
22msg="Skip all tests:"
23FUNC=all
24OUTFILE=selftest
25OUTFILE_TBENCH="$OUTFILE.tbench"
26OUTFILE_GIT="$OUTFILE.gitsource"
27
28PERF=/usr/bin/perf
29SYSFS=
30CPUROOT=
31CPUFREQROOT=
32MAKE_CPUS=
33
34TIME_LIMIT=100
35PROCESS_NUM=128
36LOOP_TIMES=3
37TRACER_INTERVAL=10
38CURRENT_TEST=amd-pstate
39COMPARATIVE_TEST=
40
41# Kselftest framework requirement - SKIP code is 4.
42ksft_skip=4
43all_scaling_names=("acpi-cpufreq" "amd-pstate")
44
45# Get current cpufreq scaling driver name
46scaling_name()
47{
48	if [ "$COMPARATIVE_TEST" = "" ]; then
49		echo "$CURRENT_TEST"
50	else
51		echo "$COMPARATIVE_TEST"
52	fi
53}
54
55# Counts CPUs with cpufreq directories
56count_cpus()
57{
58	count=0;
59
60	for cpu in `ls $CPUROOT | grep "cpu[0-9].*"`; do
61		if [ -d $CPUROOT/$cpu/cpufreq ]; then
62			let count=count+1;
63		fi
64	done
65
66	echo $count;
67}
68
69# $1: policy
70find_current_governor()
71{
72	cat $CPUFREQROOT/$1/scaling_governor
73}
74
75backup_governor()
76{
77	policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
78	for policy in $policies; do
79		cur_gov=$(find_current_governor $policy)
80		echo "$policy $cur_gov" >> $OUTFILE.backup_governor.log
81	done
82
83	printf "Governor $cur_gov backup done.\n"
84}
85
86restore_governor()
87{
88	i=0;
89
90	policies=$(awk '{print $1}' $OUTFILE.backup_governor.log)
91	for policy in $policies; do
92		let i++;
93		governor=$(sed -n ''$i'p' $OUTFILE.backup_governor.log | awk '{print $2}')
94
95		# switch governor
96		echo $governor > $CPUFREQROOT/$policy/scaling_governor
97	done
98
99	printf "Governor restored to $governor.\n"
100}
101
102# $1: governor
103switch_governor()
104{
105	policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
106	for policy in $policies; do
107		filepath=$CPUFREQROOT/$policy/scaling_available_governors
108
109		# Exit if cpu isn't managed by cpufreq core
110		if [ ! -f $filepath ]; then
111			return;
112		fi
113
114		echo $1 > $CPUFREQROOT/$policy/scaling_governor
115	done
116
117	printf "Switched governor to $1.\n"
118}
119
120# All amd-pstate tests
121amd_pstate_all()
122{
123	printf "\n=============================================\n"
124	printf "***** Running AMD P-state Sanity Tests  *****\n"
125	printf "=============================================\n\n"
126
127	count=$(count_cpus)
128	if [ $count = 0 ]; then
129		printf "No cpu is managed by cpufreq core, exiting\n"
130		exit;
131	else
132		printf "AMD P-state manages: $count CPUs\n"
133	fi
134
135	# unit test for amd-pstate kernel driver
136	amd_pstate_basic
137
138	# tbench
139	amd_pstate_tbench
140
141	# gitsource
142	amd_pstate_gitsource
143}
144
145help()
146{
147	printf "Usage: $0 [OPTION...]
148	[-h <help>]
149	[-o <output-file-for-dump>]
150	[-c <all: All testing,
151	     basic: Basic testing,
152	     tbench: Tbench testing,
153	     gitsource: Gitsource testing.>]
154	[-t <tbench time limit>]
155	[-p <tbench process number>]
156	[-l <loop times for tbench>]
157	[-i <amd tracer interval>]
158	[-b <perf binary>]
159	[-m <comparative test: acpi-cpufreq>]
160	\n"
161	exit 2
162}
163
164parse_arguments()
165{
166	while getopts ho:c:t:p:l:i:b:m: arg
167	do
168		case $arg in
169			h) # --help
170				help
171				;;
172
173			c) # --func_type (Function to perform: basic, tbench, gitsource (default: all))
174				FUNC=$OPTARG
175				;;
176
177			o) # --output-file (Output file to store dumps)
178				OUTFILE=$OPTARG
179				;;
180
181			t) # --tbench-time-limit
182				TIME_LIMIT=$OPTARG
183				;;
184
185			p) # --tbench-process-number
186				PROCESS_NUM=$OPTARG
187				;;
188
189			l) # --tbench/gitsource-loop-times
190				LOOP_TIMES=$OPTARG
191				;;
192
193			i) # --amd-tracer-interval
194				TRACER_INTERVAL=$OPTARG
195				;;
196
197			b) # --perf-binary
198				PERF=`realpath $OPTARG`
199				;;
200
201			m) # --comparative-test
202				COMPARATIVE_TEST=$OPTARG
203				;;
204
205			*)
206				help
207				;;
208		esac
209	done
210}
211
212command_perf()
213{
214	if ! $PERF -v; then
215		echo $msg please install perf or provide perf binary path as argument >&2
216		exit $ksft_skip
217	fi
218}
219
220command_tbench()
221{
222	if ! command -v tbench > /dev/null; then
223		if apt policy dbench > /dev/null 2>&1; then
224			echo $msg apt install dbench >&2
225			exit $ksft_skip
226		elif yum list available | grep dbench > /dev/null 2>&1; then
227			echo $msg yum install dbench >&2
228			exit $ksft_skip
229		fi
230	fi
231
232	if ! command -v tbench > /dev/null; then
233		echo $msg please install tbench. >&2
234		exit $ksft_skip
235	fi
236}
237
238prerequisite()
239{
240	if ! echo "$ARCH" | grep -q x86; then
241		echo "$0 # Skipped: Test can only run on x86 architectures."
242		exit $ksft_skip
243	fi
244
245	if ! echo "$VENDOR" | grep -iq amd; then
246		echo "$0 # Skipped: Test can only run on AMD CPU."
247		echo "$0 # Current cpu vendor is $VENDOR."
248		exit $ksft_skip
249	fi
250
251	scaling_driver=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_driver)
252	if [ "$COMPARATIVE_TEST" = "" ]; then
253		if [ "$scaling_driver" != "$CURRENT_TEST" ]; then
254			echo "$0 # Skipped: Test can only run on $CURRENT_TEST driver or run comparative test."
255			echo "$0 # Please set X86_AMD_PSTATE enabled or run comparative test."
256			echo "$0 # Current cpufreq scaling driver is $scaling_driver."
257			exit $ksft_skip
258		fi
259	else
260		case "$FUNC" in
261			"tbench" | "gitsource")
262				if [ "$scaling_driver" != "$COMPARATIVE_TEST" ]; then
263					echo "$0 # Skipped: Comparison test can only run on $COMPARISON_TEST driver."
264					echo "$0 # Current cpufreq scaling driver is $scaling_driver."
265					exit $ksft_skip
266				fi
267				;;
268
269			*)
270				echo "$0 # Skipped: Comparison test are only for tbench or gitsource."
271				echo "$0 # Current comparative test is for $FUNC."
272				exit $ksft_skip
273				;;
274		esac
275	fi
276
277	if [ ! -w /dev ]; then
278		echo $msg please run this as root >&2
279		exit $ksft_skip
280	fi
281
282	case "$FUNC" in
283		"all")
284			command_perf
285			command_tbench
286			;;
287
288		"tbench")
289			command_perf
290			command_tbench
291			;;
292
293		"gitsource")
294			command_perf
295			;;
296	esac
297
298	SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
299
300	if [ ! -d "$SYSFS" ]; then
301		echo $msg sysfs is not mounted >&2
302		exit 2
303	fi
304
305	CPUROOT=$SYSFS/devices/system/cpu
306	CPUFREQROOT="$CPUROOT/cpufreq"
307
308	if ! ls $CPUROOT/cpu* > /dev/null 2>&1; then
309		echo $msg cpus not available in sysfs >&2
310		exit 2
311	fi
312
313	if ! ls $CPUROOT/cpufreq > /dev/null 2>&1; then
314		echo $msg cpufreq directory not available in sysfs >&2
315		exit 2
316	fi
317}
318
319do_test()
320{
321	# Check if CPUs are managed by cpufreq or not
322	count=$(count_cpus)
323	MAKE_CPUS=$((count*2))
324
325	if [ $count = 0 ]; then
326		echo "No cpu is managed by cpufreq core, exiting"
327		exit 2;
328	fi
329
330	case "$FUNC" in
331		"all")
332			amd_pstate_all
333			;;
334
335		"basic")
336			amd_pstate_basic
337			;;
338
339		"tbench")
340			amd_pstate_tbench
341			;;
342
343		"gitsource")
344			amd_pstate_gitsource
345			;;
346
347		*)
348			echo "Invalid [-f] function type"
349			help
350			;;
351	esac
352}
353
354# clear dumps
355pre_clear_dumps()
356{
357	case "$FUNC" in
358		"all")
359			rm -rf $OUTFILE.log
360			rm -rf $OUTFILE.backup_governor.log
361			rm -rf *.png
362			;;
363
364		"tbench")
365			rm -rf $OUTFILE.log
366			rm -rf $OUTFILE.backup_governor.log
367			rm -rf tbench_*.png
368			;;
369
370		"gitsource")
371			rm -rf $OUTFILE.log
372			rm -rf $OUTFILE.backup_governor.log
373			rm -rf gitsource_*.png
374			;;
375
376		*)
377			;;
378	esac
379}
380
381post_clear_dumps()
382{
383	rm -rf $OUTFILE.log
384	rm -rf $OUTFILE.backup_governor.log
385}
386
387# Parse arguments
388parse_arguments $@
389
390# Make sure all requirements are met
391prerequisite
392
393# Run requested functions
394pre_clear_dumps
395do_test | tee -a $OUTFILE.log
396post_clear_dumps
397