162306a36Sopenharmony_ci#!/bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# 462306a36Sopenharmony_ci# This test runs on Intel x86 based hardware which support the intel_pstate 562306a36Sopenharmony_ci# driver. The test checks the frequency settings from the maximum turbo 662306a36Sopenharmony_ci# state to the minimum supported frequency, in decrements of 100MHz. The 762306a36Sopenharmony_ci# test runs the aperf.c program to put load on each processor. 862306a36Sopenharmony_ci# 962306a36Sopenharmony_ci# The results are displayed in a table which indicate the "Target" state, 1062306a36Sopenharmony_ci# or the requested frequency in MHz, the Actual frequency, as read from 1162306a36Sopenharmony_ci# /proc/cpuinfo, the difference between the Target and Actual frequencies, 1262306a36Sopenharmony_ci# and the value of MSR 0x199 (MSR_IA32_PERF_CTL) which indicates what 1362306a36Sopenharmony_ci# pstate the cpu is in, and the value of 1462306a36Sopenharmony_ci# /sys/devices/system/cpu/intel_pstate/max_perf_pct X maximum turbo state 1562306a36Sopenharmony_ci# 1662306a36Sopenharmony_ci# Notes: In some cases several frequency values may be placed in the 1762306a36Sopenharmony_ci# /tmp/result.X files. This is done on purpose in order to catch cases 1862306a36Sopenharmony_ci# where the pstate driver may not be working at all. There is the case 1962306a36Sopenharmony_ci# where, for example, several "similar" frequencies are in the file: 2062306a36Sopenharmony_ci# 2162306a36Sopenharmony_ci# 2262306a36Sopenharmony_ci#/tmp/result.3100:1:cpu MHz : 2899.980 2362306a36Sopenharmony_ci#/tmp/result.3100:2:cpu MHz : 2900.000 2462306a36Sopenharmony_ci#/tmp/result.3100:3:msr 0x199: 0x1e00 2562306a36Sopenharmony_ci#/tmp/result.3100:4:max_perf_pct 94 2662306a36Sopenharmony_ci# 2762306a36Sopenharmony_ci# and the test will error out in those cases. The result.X file can be checked 2862306a36Sopenharmony_ci# for consistency and modified to remove the extra MHz values. The result.X 2962306a36Sopenharmony_ci# files can be re-evaluated by setting EVALUATE_ONLY to 1 below. 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciEVALUATE_ONLY=0 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci# Kselftest framework requirement - SKIP code is 4. 3462306a36Sopenharmony_ciksft_skip=4 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ciif ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then 3762306a36Sopenharmony_ci echo "$0 # Skipped: Test can only run on x86 architectures." 3862306a36Sopenharmony_ci exit $ksft_skip 3962306a36Sopenharmony_cifi 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cimsg="skip all tests:" 4262306a36Sopenharmony_ciif [ $UID != 0 ] && [ $EVALUATE_ONLY == 0 ]; then 4362306a36Sopenharmony_ci echo $msg please run this as root >&2 4462306a36Sopenharmony_ci exit $ksft_skip 4562306a36Sopenharmony_cifi 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cimax_cpus=$(($(nproc)-1)) 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cifunction run_test () { 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci file_ext=$1 5262306a36Sopenharmony_ci for cpu in `seq 0 $max_cpus` 5362306a36Sopenharmony_ci do 5462306a36Sopenharmony_ci echo "launching aperf load on $cpu" 5562306a36Sopenharmony_ci ./aperf $cpu & 5662306a36Sopenharmony_ci done 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci echo "sleeping for 5 seconds" 5962306a36Sopenharmony_ci sleep 5 6062306a36Sopenharmony_ci grep MHz /proc/cpuinfo | sort -u > /tmp/result.freqs 6162306a36Sopenharmony_ci num_freqs=$(wc -l /tmp/result.freqs | awk ' { print $1 } ') 6262306a36Sopenharmony_ci if [ $num_freqs -ge 2 ]; then 6362306a36Sopenharmony_ci tail -n 1 /tmp/result.freqs > /tmp/result.$1 6462306a36Sopenharmony_ci else 6562306a36Sopenharmony_ci cp /tmp/result.freqs /tmp/result.$1 6662306a36Sopenharmony_ci fi 6762306a36Sopenharmony_ci ./msr 0 >> /tmp/result.$1 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci max_perf_pct=$(cat /sys/devices/system/cpu/intel_pstate/max_perf_pct) 7062306a36Sopenharmony_ci echo "max_perf_pct $max_perf_pct" >> /tmp/result.$1 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci for job in `jobs -p` 7362306a36Sopenharmony_ci do 7462306a36Sopenharmony_ci echo "waiting for job id $job" 7562306a36Sopenharmony_ci wait $job 7662306a36Sopenharmony_ci done 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci# 8062306a36Sopenharmony_ci# MAIN (ALL UNITS IN MHZ) 8162306a36Sopenharmony_ci# 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci# Get the marketing frequency 8462306a36Sopenharmony_ci_mkt_freq=$(cat /proc/cpuinfo | grep -m 1 "model name" | awk '{print $NF}') 8562306a36Sopenharmony_ci_mkt_freq=$(echo $_mkt_freq | tr -d [:alpha:][:punct:]) 8662306a36Sopenharmony_cimkt_freq=${_mkt_freq}0 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci# Get the ranges from cpupower 8962306a36Sopenharmony_ci_min_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $1 } ') 9062306a36Sopenharmony_cimin_freq=$(($_min_freq / 1000)) 9162306a36Sopenharmony_ci_max_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $2 } ') 9262306a36Sopenharmony_cimax_freq=$(($_max_freq / 1000)) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci[ $EVALUATE_ONLY -eq 0 ] && for freq in `seq $max_freq -100 $min_freq` 9662306a36Sopenharmony_cido 9762306a36Sopenharmony_ci echo "Setting maximum frequency to $freq" 9862306a36Sopenharmony_ci cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null 9962306a36Sopenharmony_ci run_test $freq 10062306a36Sopenharmony_cidone 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci[ $EVALUATE_ONLY -eq 0 ] && cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciecho "========================================================================" 10562306a36Sopenharmony_ciecho "The marketing frequency of the cpu is $mkt_freq MHz" 10662306a36Sopenharmony_ciecho "The maximum frequency of the cpu is $max_freq MHz" 10762306a36Sopenharmony_ciecho "The minimum frequency of the cpu is $min_freq MHz" 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci# make a pretty table 11062306a36Sopenharmony_ciecho "Target Actual Difference MSR(0x199) max_perf_pct" | tr " " "\n" > /tmp/result.tab 11162306a36Sopenharmony_cifor freq in `seq $max_freq -100 $min_freq` 11262306a36Sopenharmony_cido 11362306a36Sopenharmony_ci result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ') 11462306a36Sopenharmony_ci msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ') 11562306a36Sopenharmony_ci max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' ) 11662306a36Sopenharmony_ci cat >> /tmp/result.tab << EOF 11762306a36Sopenharmony_ci$freq 11862306a36Sopenharmony_ci$result_freq 11962306a36Sopenharmony_ci$((result_freq - freq)) 12062306a36Sopenharmony_ci$msr 12162306a36Sopenharmony_ci$((max_perf_pct * max_freq)) 12262306a36Sopenharmony_ciEOF 12362306a36Sopenharmony_cidone 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci# print the table 12662306a36Sopenharmony_cipr -aTt -5 < /tmp/result.tab 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciexit 0 129