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