xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/intel_pstate/run.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# This test runs on Intel x86 based hardware which support the intel_pstate
5*4882a593Smuzhiyun# driver.  The test checks the frequency settings from the maximum turbo
6*4882a593Smuzhiyun# state to the minimum supported frequency, in decrements of 100MHz.  The
7*4882a593Smuzhiyun# test runs the aperf.c program to put load on each processor.
8*4882a593Smuzhiyun#
9*4882a593Smuzhiyun# The results are displayed in a table which indicate the "Target" state,
10*4882a593Smuzhiyun# or the requested frequency in MHz, the Actual frequency, as read from
11*4882a593Smuzhiyun# /proc/cpuinfo, the difference between the Target and Actual frequencies,
12*4882a593Smuzhiyun# and the value of MSR 0x199 (MSR_IA32_PERF_CTL) which indicates what
13*4882a593Smuzhiyun# pstate the cpu is in, and the value of
14*4882a593Smuzhiyun# /sys/devices/system/cpu/intel_pstate/max_perf_pct X maximum turbo state
15*4882a593Smuzhiyun#
16*4882a593Smuzhiyun# Notes: In some cases several frequency values may be placed in the
17*4882a593Smuzhiyun# /tmp/result.X files.  This is done on purpose in order to catch cases
18*4882a593Smuzhiyun# where the pstate driver may not be working at all.  There is the case
19*4882a593Smuzhiyun# where, for example, several "similar" frequencies are in the file:
20*4882a593Smuzhiyun#
21*4882a593Smuzhiyun#
22*4882a593Smuzhiyun#/tmp/result.3100:1:cpu MHz              : 2899.980
23*4882a593Smuzhiyun#/tmp/result.3100:2:cpu MHz              : 2900.000
24*4882a593Smuzhiyun#/tmp/result.3100:3:msr 0x199: 0x1e00
25*4882a593Smuzhiyun#/tmp/result.3100:4:max_perf_pct 94
26*4882a593Smuzhiyun#
27*4882a593Smuzhiyun# and the test will error out in those cases.  The result.X file can be checked
28*4882a593Smuzhiyun# for consistency and modified to remove the extra MHz values.  The result.X
29*4882a593Smuzhiyun# files can be re-evaluated by setting EVALUATE_ONLY to 1 below.
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunEVALUATE_ONLY=0
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun# Kselftest framework requirement - SKIP code is 4.
34*4882a593Smuzhiyunksft_skip=4
35*4882a593Smuzhiyun
36*4882a593Smuzhiyunif ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then
37*4882a593Smuzhiyun	echo "$0 # Skipped: Test can only run on x86 architectures."
38*4882a593Smuzhiyun	exit $ksft_skip
39*4882a593Smuzhiyunfi
40*4882a593Smuzhiyun
41*4882a593Smuzhiyunmsg="skip all tests:"
42*4882a593Smuzhiyunif [ $UID != 0 ] && [ $EVALUATE_ONLY == 0 ]; then
43*4882a593Smuzhiyun    echo $msg please run this as root >&2
44*4882a593Smuzhiyun    exit $ksft_skip
45*4882a593Smuzhiyunfi
46*4882a593Smuzhiyun
47*4882a593Smuzhiyunmax_cpus=$(($(nproc)-1))
48*4882a593Smuzhiyun
49*4882a593Smuzhiyunfunction run_test () {
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun	file_ext=$1
52*4882a593Smuzhiyun	for cpu in `seq 0 $max_cpus`
53*4882a593Smuzhiyun	do
54*4882a593Smuzhiyun		echo "launching aperf load on $cpu"
55*4882a593Smuzhiyun		./aperf $cpu &
56*4882a593Smuzhiyun	done
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun	echo "sleeping for 5 seconds"
59*4882a593Smuzhiyun	sleep 5
60*4882a593Smuzhiyun	grep MHz /proc/cpuinfo | sort -u > /tmp/result.freqs
61*4882a593Smuzhiyun	num_freqs=$(wc -l /tmp/result.freqs | awk ' { print $1 } ')
62*4882a593Smuzhiyun	if [ $num_freqs -ge 2 ]; then
63*4882a593Smuzhiyun		tail -n 1 /tmp/result.freqs > /tmp/result.$1
64*4882a593Smuzhiyun	else
65*4882a593Smuzhiyun		cp /tmp/result.freqs /tmp/result.$1
66*4882a593Smuzhiyun	fi
67*4882a593Smuzhiyun	./msr 0 >> /tmp/result.$1
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun	max_perf_pct=$(cat /sys/devices/system/cpu/intel_pstate/max_perf_pct)
70*4882a593Smuzhiyun	echo "max_perf_pct $max_perf_pct" >> /tmp/result.$1
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun	for job in `jobs -p`
73*4882a593Smuzhiyun	do
74*4882a593Smuzhiyun		echo "waiting for job id $job"
75*4882a593Smuzhiyun		wait $job
76*4882a593Smuzhiyun	done
77*4882a593Smuzhiyun}
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun#
80*4882a593Smuzhiyun# MAIN (ALL UNITS IN MHZ)
81*4882a593Smuzhiyun#
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun# Get the marketing frequency
84*4882a593Smuzhiyun_mkt_freq=$(cat /proc/cpuinfo | grep -m 1 "model name" | awk '{print $NF}')
85*4882a593Smuzhiyun_mkt_freq=$(echo $_mkt_freq | tr -d [:alpha:][:punct:])
86*4882a593Smuzhiyunmkt_freq=${_mkt_freq}0
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun# Get the ranges from cpupower
89*4882a593Smuzhiyun_min_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $1 } ')
90*4882a593Smuzhiyunmin_freq=$(($_min_freq / 1000))
91*4882a593Smuzhiyun_max_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $2 } ')
92*4882a593Smuzhiyunmax_freq=$(($_max_freq / 1000))
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun[ $EVALUATE_ONLY -eq 0 ] && for freq in `seq $max_freq -100 $min_freq`
96*4882a593Smuzhiyundo
97*4882a593Smuzhiyun	echo "Setting maximum frequency to $freq"
98*4882a593Smuzhiyun	cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null
99*4882a593Smuzhiyun	run_test $freq
100*4882a593Smuzhiyundone
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun[ $EVALUATE_ONLY -eq 0 ] && cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null
103*4882a593Smuzhiyun
104*4882a593Smuzhiyunecho "========================================================================"
105*4882a593Smuzhiyunecho "The marketing frequency of the cpu is $mkt_freq MHz"
106*4882a593Smuzhiyunecho "The maximum frequency of the cpu is $max_freq MHz"
107*4882a593Smuzhiyunecho "The minimum frequency of the cpu is $min_freq MHz"
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun# make a pretty table
110*4882a593Smuzhiyunecho "Target Actual Difference MSR(0x199) max_perf_pct" | tr " " "\n" > /tmp/result.tab
111*4882a593Smuzhiyunfor freq in `seq $max_freq -100 $min_freq`
112*4882a593Smuzhiyundo
113*4882a593Smuzhiyun	result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ')
114*4882a593Smuzhiyun	msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ')
115*4882a593Smuzhiyun	max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' )
116*4882a593Smuzhiyun	cat >> /tmp/result.tab << EOF
117*4882a593Smuzhiyun$freq
118*4882a593Smuzhiyun$result_freq
119*4882a593Smuzhiyun$((result_freq - freq))
120*4882a593Smuzhiyun$msr
121*4882a593Smuzhiyun$((max_perf_pct * max_freq))
122*4882a593SmuzhiyunEOF
123*4882a593Smuzhiyundone
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun# print the table
126*4882a593Smuzhiyunpr -aTt -5 < /tmp/result.tab
127*4882a593Smuzhiyun
128*4882a593Smuzhiyunexit 0
129