397 lines
7.3 KiB
Bash
Executable File
397 lines
7.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
# protect against multiple inclusion
|
|
if [ $FILE_MAIN ]; then
|
|
return 0
|
|
else
|
|
FILE_MAIN=DONE
|
|
fi
|
|
|
|
SCRIPTDIR=`dirname "$0"`
|
|
TRACER=$SCRIPTDIR/../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py
|
|
|
|
source $SCRIPTDIR/basic.sh
|
|
source $SCRIPTDIR/tbench.sh
|
|
source $SCRIPTDIR/gitsource.sh
|
|
|
|
# amd-pstate-ut only run on x86/x86_64 AMD systems.
|
|
ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/')
|
|
VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}')
|
|
|
|
msg="Skip all tests:"
|
|
FUNC=all
|
|
OUTFILE=selftest
|
|
OUTFILE_TBENCH="$OUTFILE.tbench"
|
|
OUTFILE_GIT="$OUTFILE.gitsource"
|
|
|
|
PERF=/usr/bin/perf
|
|
SYSFS=
|
|
CPUROOT=
|
|
CPUFREQROOT=
|
|
MAKE_CPUS=
|
|
|
|
TIME_LIMIT=100
|
|
PROCESS_NUM=128
|
|
LOOP_TIMES=3
|
|
TRACER_INTERVAL=10
|
|
CURRENT_TEST=amd-pstate
|
|
COMPARATIVE_TEST=
|
|
|
|
# Kselftest framework requirement - SKIP code is 4.
|
|
ksft_skip=4
|
|
all_scaling_names=("acpi-cpufreq" "amd-pstate")
|
|
|
|
# Get current cpufreq scaling driver name
|
|
scaling_name()
|
|
{
|
|
if [ "$COMPARATIVE_TEST" = "" ]; then
|
|
echo "$CURRENT_TEST"
|
|
else
|
|
echo "$COMPARATIVE_TEST"
|
|
fi
|
|
}
|
|
|
|
# Counts CPUs with cpufreq directories
|
|
count_cpus()
|
|
{
|
|
count=0;
|
|
|
|
for cpu in `ls $CPUROOT | grep "cpu[0-9].*"`; do
|
|
if [ -d $CPUROOT/$cpu/cpufreq ]; then
|
|
let count=count+1;
|
|
fi
|
|
done
|
|
|
|
echo $count;
|
|
}
|
|
|
|
# $1: policy
|
|
find_current_governor()
|
|
{
|
|
cat $CPUFREQROOT/$1/scaling_governor
|
|
}
|
|
|
|
backup_governor()
|
|
{
|
|
policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
|
|
for policy in $policies; do
|
|
cur_gov=$(find_current_governor $policy)
|
|
echo "$policy $cur_gov" >> $OUTFILE.backup_governor.log
|
|
done
|
|
|
|
printf "Governor $cur_gov backup done.\n"
|
|
}
|
|
|
|
restore_governor()
|
|
{
|
|
i=0;
|
|
|
|
policies=$(awk '{print $1}' $OUTFILE.backup_governor.log)
|
|
for policy in $policies; do
|
|
let i++;
|
|
governor=$(sed -n ''$i'p' $OUTFILE.backup_governor.log | awk '{print $2}')
|
|
|
|
# switch governor
|
|
echo $governor > $CPUFREQROOT/$policy/scaling_governor
|
|
done
|
|
|
|
printf "Governor restored to $governor.\n"
|
|
}
|
|
|
|
# $1: governor
|
|
switch_governor()
|
|
{
|
|
policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
|
|
for policy in $policies; do
|
|
filepath=$CPUFREQROOT/$policy/scaling_available_governors
|
|
|
|
# Exit if cpu isn't managed by cpufreq core
|
|
if [ ! -f $filepath ]; then
|
|
return;
|
|
fi
|
|
|
|
echo $1 > $CPUFREQROOT/$policy/scaling_governor
|
|
done
|
|
|
|
printf "Switched governor to $1.\n"
|
|
}
|
|
|
|
# All amd-pstate tests
|
|
amd_pstate_all()
|
|
{
|
|
printf "\n=============================================\n"
|
|
printf "***** Running AMD P-state Sanity Tests *****\n"
|
|
printf "=============================================\n\n"
|
|
|
|
count=$(count_cpus)
|
|
if [ $count = 0 ]; then
|
|
printf "No cpu is managed by cpufreq core, exiting\n"
|
|
exit;
|
|
else
|
|
printf "AMD P-state manages: $count CPUs\n"
|
|
fi
|
|
|
|
# unit test for amd-pstate kernel driver
|
|
amd_pstate_basic
|
|
|
|
# tbench
|
|
amd_pstate_tbench
|
|
|
|
# gitsource
|
|
amd_pstate_gitsource
|
|
}
|
|
|
|
help()
|
|
{
|
|
printf "Usage: $0 [OPTION...]
|
|
[-h <help>]
|
|
[-o <output-file-for-dump>]
|
|
[-c <all: All testing,
|
|
basic: Basic testing,
|
|
tbench: Tbench testing,
|
|
gitsource: Gitsource testing.>]
|
|
[-t <tbench time limit>]
|
|
[-p <tbench process number>]
|
|
[-l <loop times for tbench>]
|
|
[-i <amd tracer interval>]
|
|
[-b <perf binary>]
|
|
[-m <comparative test: acpi-cpufreq>]
|
|
\n"
|
|
exit 2
|
|
}
|
|
|
|
parse_arguments()
|
|
{
|
|
while getopts ho:c:t:p:l:i:b:m: arg
|
|
do
|
|
case $arg in
|
|
h) # --help
|
|
help
|
|
;;
|
|
|
|
c) # --func_type (Function to perform: basic, tbench, gitsource (default: all))
|
|
FUNC=$OPTARG
|
|
;;
|
|
|
|
o) # --output-file (Output file to store dumps)
|
|
OUTFILE=$OPTARG
|
|
;;
|
|
|
|
t) # --tbench-time-limit
|
|
TIME_LIMIT=$OPTARG
|
|
;;
|
|
|
|
p) # --tbench-process-number
|
|
PROCESS_NUM=$OPTARG
|
|
;;
|
|
|
|
l) # --tbench/gitsource-loop-times
|
|
LOOP_TIMES=$OPTARG
|
|
;;
|
|
|
|
i) # --amd-tracer-interval
|
|
TRACER_INTERVAL=$OPTARG
|
|
;;
|
|
|
|
b) # --perf-binary
|
|
PERF=`realpath $OPTARG`
|
|
;;
|
|
|
|
m) # --comparative-test
|
|
COMPARATIVE_TEST=$OPTARG
|
|
;;
|
|
|
|
*)
|
|
help
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
command_perf()
|
|
{
|
|
if ! $PERF -v; then
|
|
echo $msg please install perf or provide perf binary path as argument >&2
|
|
exit $ksft_skip
|
|
fi
|
|
}
|
|
|
|
command_tbench()
|
|
{
|
|
if ! command -v tbench > /dev/null; then
|
|
if apt policy dbench > /dev/null 2>&1; then
|
|
echo $msg apt install dbench >&2
|
|
exit $ksft_skip
|
|
elif yum list available | grep dbench > /dev/null 2>&1; then
|
|
echo $msg yum install dbench >&2
|
|
exit $ksft_skip
|
|
fi
|
|
fi
|
|
|
|
if ! command -v tbench > /dev/null; then
|
|
echo $msg please install tbench. >&2
|
|
exit $ksft_skip
|
|
fi
|
|
}
|
|
|
|
prerequisite()
|
|
{
|
|
if ! echo "$ARCH" | grep -q x86; then
|
|
echo "$0 # Skipped: Test can only run on x86 architectures."
|
|
exit $ksft_skip
|
|
fi
|
|
|
|
if ! echo "$VENDOR" | grep -iq amd; then
|
|
echo "$0 # Skipped: Test can only run on AMD CPU."
|
|
echo "$0 # Current cpu vendor is $VENDOR."
|
|
exit $ksft_skip
|
|
fi
|
|
|
|
scaling_driver=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_driver)
|
|
if [ "$COMPARATIVE_TEST" = "" ]; then
|
|
if [ "$scaling_driver" != "$CURRENT_TEST" ]; then
|
|
echo "$0 # Skipped: Test can only run on $CURRENT_TEST driver or run comparative test."
|
|
echo "$0 # Please set X86_AMD_PSTATE enabled or run comparative test."
|
|
echo "$0 # Current cpufreq scaling driver is $scaling_driver."
|
|
exit $ksft_skip
|
|
fi
|
|
else
|
|
case "$FUNC" in
|
|
"tbench" | "gitsource")
|
|
if [ "$scaling_driver" != "$COMPARATIVE_TEST" ]; then
|
|
echo "$0 # Skipped: Comparison test can only run on $COMPARISON_TEST driver."
|
|
echo "$0 # Current cpufreq scaling driver is $scaling_driver."
|
|
exit $ksft_skip
|
|
fi
|
|
;;
|
|
|
|
*)
|
|
echo "$0 # Skipped: Comparison test are only for tbench or gitsource."
|
|
echo "$0 # Current comparative test is for $FUNC."
|
|
exit $ksft_skip
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [ ! -w /dev ]; then
|
|
echo $msg please run this as root >&2
|
|
exit $ksft_skip
|
|
fi
|
|
|
|
case "$FUNC" in
|
|
"all")
|
|
command_perf
|
|
command_tbench
|
|
;;
|
|
|
|
"tbench")
|
|
command_perf
|
|
command_tbench
|
|
;;
|
|
|
|
"gitsource")
|
|
command_perf
|
|
;;
|
|
esac
|
|
|
|
SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
|
|
|
|
if [ ! -d "$SYSFS" ]; then
|
|
echo $msg sysfs is not mounted >&2
|
|
exit 2
|
|
fi
|
|
|
|
CPUROOT=$SYSFS/devices/system/cpu
|
|
CPUFREQROOT="$CPUROOT/cpufreq"
|
|
|
|
if ! ls $CPUROOT/cpu* > /dev/null 2>&1; then
|
|
echo $msg cpus not available in sysfs >&2
|
|
exit 2
|
|
fi
|
|
|
|
if ! ls $CPUROOT/cpufreq > /dev/null 2>&1; then
|
|
echo $msg cpufreq directory not available in sysfs >&2
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
do_test()
|
|
{
|
|
# Check if CPUs are managed by cpufreq or not
|
|
count=$(count_cpus)
|
|
MAKE_CPUS=$((count*2))
|
|
|
|
if [ $count = 0 ]; then
|
|
echo "No cpu is managed by cpufreq core, exiting"
|
|
exit 2;
|
|
fi
|
|
|
|
case "$FUNC" in
|
|
"all")
|
|
amd_pstate_all
|
|
;;
|
|
|
|
"basic")
|
|
amd_pstate_basic
|
|
;;
|
|
|
|
"tbench")
|
|
amd_pstate_tbench
|
|
;;
|
|
|
|
"gitsource")
|
|
amd_pstate_gitsource
|
|
;;
|
|
|
|
*)
|
|
echo "Invalid [-f] function type"
|
|
help
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# clear dumps
|
|
pre_clear_dumps()
|
|
{
|
|
case "$FUNC" in
|
|
"all")
|
|
rm -rf $OUTFILE.log
|
|
rm -rf $OUTFILE.backup_governor.log
|
|
rm -rf *.png
|
|
;;
|
|
|
|
"tbench")
|
|
rm -rf $OUTFILE.log
|
|
rm -rf $OUTFILE.backup_governor.log
|
|
rm -rf tbench_*.png
|
|
;;
|
|
|
|
"gitsource")
|
|
rm -rf $OUTFILE.log
|
|
rm -rf $OUTFILE.backup_governor.log
|
|
rm -rf gitsource_*.png
|
|
;;
|
|
|
|
*)
|
|
;;
|
|
esac
|
|
}
|
|
|
|
post_clear_dumps()
|
|
{
|
|
rm -rf $OUTFILE.log
|
|
rm -rf $OUTFILE.backup_governor.log
|
|
}
|
|
|
|
# Parse arguments
|
|
parse_arguments $@
|
|
|
|
# Make sure all requirements are met
|
|
prerequisite
|
|
|
|
# Run requested functions
|
|
pre_clear_dumps
|
|
do_test | tee -a $OUTFILE.log
|
|
post_clear_dumps
|