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