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 11source basic.sh 12source tbench.sh 13source gitsource.sh 14 15# amd-pstate-ut only run on x86/x86_64 AMD systems. 16ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/') 17VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}') 18 19msg="Skip all tests:" 20FUNC=all 21OUTFILE=selftest 22OUTFILE_TBENCH="$OUTFILE.tbench" 23OUTFILE_GIT="$OUTFILE.gitsource" 24 25SYSFS= 26CPUROOT= 27CPUFREQROOT= 28MAKE_CPUS= 29 30TIME_LIMIT=100 31PROCESS_NUM=128 32LOOP_TIMES=3 33TRACER_INTERVAL=10 34CURRENT_TEST=amd-pstate 35COMPARATIVE_TEST= 36 37# Kselftest framework requirement - SKIP code is 4. 38ksft_skip=4 39all_scaling_names=("acpi-cpufreq" "amd-pstate") 40 41# Get current cpufreq scaling driver name 42scaling_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 52count_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 66find_current_governor() 67{ 68 cat $CPUFREQROOT/$1/scaling_governor 69} 70 71backup_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 82restore_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 99switch_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 117amd_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 141help() 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 159parse_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 203command_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 211command_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 229prerequisite() 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 310do_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 346pre_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 372post_clear_dumps() 373{ 374 rm -rf $OUTFILE.log 375 rm -rf $OUTFILE.backup_governor.log 376} 377 378# Parse arguments 379parse_arguments $@ 380 381# Make sure all requirements are met 382prerequisite 383 384# Run requested functions 385pre_clear_dumps 386do_test | tee -a $OUTFILE.log 387post_clear_dumps 388