Hi all:
The new patches are modified on the basis of the previous patch
https://lore.kernel.org/lkml/[email protected]/.
First, we modify amd-pstate-ut.sh to basic.sh as a basic test, mainly for
AMD P-State kernel drivers. The purpose of this modification is to facilitate
the subsequent addition of gitsource, tbench and other tests.
You can test specific functions by specifying test cases.
Default test all cases, include basic, tbench and gitsource etc.
Secondly, add tbench.sh trigger the tbench testing and monitor the cpu
information.
1) Download and install tbench codes.
2) Run tbench benchmark on specific governors, ondemand or schedutil.
3) Get desire performance, frequency, load by perf.
4) Get power consumption and throughput by amd_pstate_trace.py.
5) Analyse test results and save it in file selftest.tbench.csv.
Third, add gitsource.sh trigger the gitsource testing and monitor the cpu
information.
1) Download and tar gitsource codes.
2) Run gitsource benchmark on specific governors, ondemand or schedutil.
3) Get desire performance, frequency, load by perf.
4) Get power consumption and throughput by amd_pstate_trace.py.
5) Get run time by /usr/bin/time.
6) Analyse test results and save it in file selftest.gitsource.csv.
Finally, modify rst document to introduce test steps and results etc.
Thanks,
Jasmine
Meng Li (4):
selftests: amd-pstate: Modify amd-pstate-ut.sh to basic.sh.
selftests: amd-pstate: Trigger tbench benchmark and test cpus
selftests: amd-pstate: Trigger gitsource benchmark and test cpus
Documentation: amd-pstate: Add tbench and gitsource test introduction
Documentation/admin-guide/pm/amd-pstate.rst | 124 ++++++-
tools/testing/selftests/amd-pstate/Makefile | 11 +-
.../selftests/amd-pstate/amd-pstate-ut.sh | 55 ----
tools/testing/selftests/amd-pstate/basic.sh | 38 +++
.../testing/selftests/amd-pstate/gitsource.sh | 176 ++++++++++
tools/testing/selftests/amd-pstate/main.sh | 308 ++++++++++++++++++
tools/testing/selftests/amd-pstate/run.sh | 15 +
tools/testing/selftests/amd-pstate/tbench.sh | 187 +++++++++++
8 files changed, 840 insertions(+), 74 deletions(-)
delete mode 100755 tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
create mode 100755 tools/testing/selftests/amd-pstate/basic.sh
create mode 100755 tools/testing/selftests/amd-pstate/gitsource.sh
create mode 100755 tools/testing/selftests/amd-pstate/main.sh
create mode 100755 tools/testing/selftests/amd-pstate/run.sh
create mode 100755 tools/testing/selftests/amd-pstate/tbench.sh
--
2.25.1
Introduce tbench and gitsource test cases design and implementation.
Monitor cpus changes about performance and power consumption etc.
Signed-off-by: Meng Li <[email protected]>
---
Documentation/admin-guide/pm/amd-pstate.rst | 124 +++++++++++++++++---
1 file changed, 106 insertions(+), 18 deletions(-)
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index 8f3d30c5a0d8..48fb488e000e 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -409,37 +409,53 @@ Unit Tests for amd-pstate
1. Test case decriptions
+ 1). basic tests
+
+ Test prerequisite and basic functions for the ``amd-pstate`` driver.
+
+---------+--------------------------------+------------------------------------------------------------------------------------+
| Index | Functions | Description |
+=========+================================+====================================================================================+
- | 0 | amd_pstate_ut_acpi_cpc_valid || Check whether the _CPC object is present in SBIOS. |
+ | 1 | amd_pstate_ut_acpi_cpc_valid || Check whether the _CPC object is present in SBIOS. |
| | || |
| | || The detail refer to `Processor Support <processor_support_>`_. |
+---------+--------------------------------+------------------------------------------------------------------------------------+
- | 1 | amd_pstate_ut_check_enabled || Check whether AMD P-State is enabled. |
+ | 2 | amd_pstate_ut_check_enabled || Check whether AMD P-State is enabled. |
| | || |
| | || AMD P-States and ACPI hardware P-States always can be supported in one processor. |
| | | But AMD P-States has the higher priority and if it is enabled with |
| | | :c:macro:`MSR_AMD_CPPC_ENABLE` or ``cppc_set_enable``, it will respond to the |
| | | request from AMD P-States. |
+---------+--------------------------------+------------------------------------------------------------------------------------+
- | 2 | amd_pstate_ut_check_perf || Check if the each performance values are reasonable. |
+ | 3 | amd_pstate_ut_check_perf || Check if the each performance values are reasonable. |
| | || highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0. |
+---------+--------------------------------+------------------------------------------------------------------------------------+
- | 3 | amd_pstate_ut_check_freq || Check if the each frequency values and max freq when set support boost mode |
+ | 4 | amd_pstate_ut_check_freq || Check if the each frequency values and max freq when set support boost mode |
| | | are reasonable. |
| | || max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0 |
| | || If boost is not active but supported, this maximum frequency will be larger than |
| | | the one in ``cpuinfo``. |
+---------+--------------------------------+------------------------------------------------------------------------------------+
+ 2). Tbench test
+
+ Testing and monitor the cpu changes when running tbench benchmark under the specified governor.
+ These changes include desire performance, frequency, load, performance, energy etc.
+ The specified governor is ondemand or schedutil.
+
+ 3). Gitsource test
+
+ Testing and monitor the cpu changes when running gitsource benchmark under the specified governor.
+ These changes include desire performance, frequency, load, time, energy etc.
+ The specified governor is ondemand or schedutil.
+
#. How to execute the tests
We use test module in the kselftest frameworks to implement it.
We create amd-pstate-ut module and tie it into kselftest.(for
details refer to Linux Kernel Selftests [4]_).
- 1. Build
+ a. Build
+ open the :c:macro:`CONFIG_X86_AMD_PSTATE` configuration option.
+ set the :c:macro:`CONFIG_X86_AMD_PSTATE_UT` configuration option to M.
@@ -449,23 +465,95 @@ Unit Tests for amd-pstate
$ cd linux
$ make -C tools/testing/selftests
+ + make perf ::
+
+ $ cd tools/perf/
+ $ make
+
+
#. Installation & Steps ::
$ make -C tools/testing/selftests install INSTALL_PATH=~/kselftest
+ $ cp tools/perf/perf ~/kselftest/amd-pstate/
$ sudo ./kselftest/run_kselftest.sh -c amd-pstate
- TAP version 13
- 1..1
- # selftests: amd-pstate: amd-pstate-ut.sh
- # amd-pstate-ut: ok
- ok 1 selftests: amd-pstate: amd-pstate-ut.sh
-
- #. Results ::
-
- $ dmesg | grep "amd_pstate_ut" | tee log.txt
- [12977.570663] amd_pstate_ut: 1 amd_pstate_ut_acpi_cpc_valid success!
- [12977.570673] amd_pstate_ut: 2 amd_pstate_ut_check_enabled success!
- [12977.571207] amd_pstate_ut: 3 amd_pstate_ut_check_perf success!
- [12977.571212] amd_pstate_ut: 4 amd_pstate_ut_check_freq success!
+
+ #. Specified test case ::
+
+ $ cd ~/kselftest/amd-pstate
+ $ sudo ./run.sh -t basic
+ $ sudo ./run.sh -t tbench
+ $ sudo ./run.sh -t gitsource
+ $ ./run.sh --help
+ ./run.sh: illegal option -- -
+ Usage: ./run.sh [OPTION...]
+ [-h <help>]
+ [-o <output-file-for-dump>]
+ [-t <all: All testing,
+ basic: Basic testing,
+ tbench: Test tbench,
+ gitsource: Test gitsource.>]
+ [-i <tbench time limit>]
+ [-p <tbench process number>]
+ [-l <loop times for tbench/gitsource]
+ [-n <amd tracer interval]
+
+ 4). Results
+
+ + basic
+
+ When you finish test, you will get the following log info ::
+
+ $ dmesg | grep "amd_pstate_ut" | tee log.txt
+ [12977.570663] amd_pstate_ut: 1 amd_pstate_ut_acpi_cpc_valid success!
+ [12977.570673] amd_pstate_ut: 2 amd_pstate_ut_check_enabled success!
+ [12977.571207] amd_pstate_ut: 3 amd_pstate_ut_check_perf success!
+ [12977.571212] amd_pstate_ut: 4 amd_pstate_ut_check_freq success!
+
+ + tbench
+
+ When you finish test, you will get selftest.tbench.csv and selftest.tbench.result files form amd-pstate.
+ Open selftest.tbench.csv :
+
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+ + Governor | Round | Des-perf | Freq | Load | Performance(MB/s) | Energy(Joules) | PPW(MB/J) |
+ +===========+=========+==========+=========+==========+===================+================+===========+
+ + ondemand | 1 | 203.244 | 3.2225 | 87.5064 | 35368.2 | 6626.1 | 101.4164 |
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+ + ondemand | 2 | 205.861 | 3.24948 | 88.9281 | 34795.7 | 6547.06 | 100.9794 |
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+ + ondemand | Average | 204.553 | 3.23599 | 88.2173 | 35081.9 | 6586.58 | 101.1991 |
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+ + | | | | | | | |
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+ + schedutil | 1 | 253.735 | 3.26755 | 96.6481 | 34653.9 | 6622.85 | 99.4170 |
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+ + schedutil | 2 | 254.654 | 3.44086 | 92.3564 | 31707.8 | 6573.67 | 91.6456 |
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+ + schedutil | Average | 254.195 | 3.3542 | 94.5023 | 33180.8 | 6598.26 | 95.5456 |
+ +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
+
+ + gitsource
+
+ When you finish test, you will get selftest.gitsource.csv and selftest.gitsource.result files form amd-pstate.
+ Open selftest.gitsource.csv :
+
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
+ + Governor | Round | Des-perf | Freq | Load | Times(s) | Energy(Joules) | PPW(s/J) |
+ +===========+=========+==========+==========+==========+==========+================+==========+
+ + ondemand | 1 | 29.7305 | 1.13025 | 8.49585 | 341.61 | 6811.02 | 0.0501 |
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
+ + ondemand | 2 | 28.0523 | 1.33848 | 8.16496 | 339.21 | 6999.84 | 0.0484 |
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
+ + ondemand | Average | 28.8914 | 1.23436 | 8.33041 | 340.41 | 6905.43 | 0.0492 |
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
+ + | | | | | | | |
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
+ + schedutil | 1 | 29.6971 | 0.834149 | 9.57879 | 278.15 | 5992.26 | 0.0464 |
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
+ + schedutil | 2 | 31.6573 | 0.99686 | 8.60513 | 280.28 | 5772.59 | 0.0485 |
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
+ + schedutil | Average | 30.6772 | 0.915504 | 9.09196 | 279.215 | 5882.43 | 0.0474 |
+ +-----------+---------+----------+----------+----------+----------+----------------+----------+
Reference
===========
--
2.25.1
Add gitsource.sh trigger the gitsource testing and monitor the cpu desire
performance, frequency, load, power consumption and throughput etc.
Signed-off-by: Meng Li <[email protected]>
---
tools/testing/selftests/amd-pstate/Makefile | 2 +-
.../testing/selftests/amd-pstate/gitsource.sh | 176 ++++++++++++++++++
tools/testing/selftests/amd-pstate/main.sh | 21 ++-
3 files changed, 195 insertions(+), 4 deletions(-)
create mode 100755 tools/testing/selftests/amd-pstate/gitsource.sh
diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
index e2fb03381a32..c536b9303858 100644
--- a/tools/testing/selftests/amd-pstate/Makefile
+++ b/tools/testing/selftests/amd-pstate/Makefile
@@ -13,6 +13,6 @@ TEST_GEN_FILES += ../../../power/x86/intel_pstate_tracer/intel_pstate_tracer.py
endif
TEST_PROGS := run.sh
-TEST_FILES := main.sh basic.sh tbench.sh
+TEST_FILES := main.sh basic.sh tbench.sh gitsource.sh
include ../lib.mk
diff --git a/tools/testing/selftests/amd-pstate/gitsource.sh b/tools/testing/selftests/amd-pstate/gitsource.sh
new file mode 100755
index 000000000000..0631a4839f5d
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/gitsource.sh
@@ -0,0 +1,176 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+# Testing and monitor the cpu frequency and performance when
+# this script trigger gitsource test.
+
+# protect against multiple inclusion
+if [ $FILE_GITSOURCE ]; then
+ return 0
+else
+ FILE_GITSOURCE=DONE
+fi
+
+git_name="git-2.15.1"
+git_tar="$git_name.tar.gz"
+gitsource_url="https://github.com/git/git/archive/refs/tags/v2.15.1.tar.gz"
+gitsource_governors=("ondemand" "schedutil")
+
+# $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: time $7: energy, $8: PPW
+store_csv_gitsource()
+{
+ echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_GIT.csv > /dev/null 2>&1
+}
+
+empty_line_csv_gitsource()
+{
+ echo "" | tee -a $OUTFILE_GIT.csv > /dev/null 2>&1
+}
+
+pre_clear_gitsource()
+{
+ rm -rf results/tracer-gitsource*
+}
+
+post_clear_gitsource()
+{
+ rm -rf results/tracer-gitsource*
+ rm -rf $OUTFILE_GIT*.log
+}
+
+install_gitsource()
+{
+ if [ ! -d $git_name ]; then
+ printf "Download gitsource, please wait a moment ...\n\n"
+ wget -O $git_tar $gitsource_url > /dev/null 2>&1
+
+ printf "Tar gitsource ...\n\n"
+ tar -xzf $git_tar
+ fi
+}
+
+# $1: governor, $2: loop
+run_gitsource()
+{
+ echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
+ ./amd_pstate_trace.py -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1
+
+ printf "Make and test gitsource for $1 #$2 make_cpus: $MAKE_CPUS\n"
+ cd $git_name
+ ./../perf stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o ../$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > ../$OUTFILE_GIT-perf-$1-$2.log 2>&1
+ cd ..
+
+ for job in `jobs -p`
+ do
+ echo "Waiting for job id $job"
+ wait $job
+ done
+}
+
+# $1: governor, $2: loop
+parse_gitsource()
+{
+ awk '{print $5}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-des-perf-$1-$2.log
+ avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-des-perf-$1-$2.log)
+ printf "Gitsource-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result
+
+ awk '{print $7}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-freq-$1-$2.log
+ avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-freq-$1-$2.log)
+ printf "Gitsource-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result
+
+ awk '{print $11}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-load-$1-$2.log
+ avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-load-$1-$2.log)
+ printf "Gitsource-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result
+
+ grep user $OUTFILE_GIT.time-gitsource-$1-$2.log | awk '{print $1}' | sed -e 's/user//' > $OUTFILE_GIT-time-$1-$2.log
+ time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1-$2.log)
+ printf "Gitsource-$1-#$2 user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result
+
+ grep Joules $OUTFILE_GIT-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_GIT-energy-$1-$2.log
+ en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1-$2.log)
+ printf "Gitsource-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
+
+ ppw=`echo "scale=4;$time_sum/$en_sum" | bc | awk '{printf "%.4f", $0}'`
+ printf "Gitsource-$1-#$2 PPW(s/J): $ppw\n" | tee -a $OUTFILE_GIT.result
+ printf "\n" | tee -a $OUTFILE_GIT.result
+
+ store_csv_gitsource $1 $2 $avg_des_perf $avg_freq $avg_load $time_sum $en_sum $ppw
+}
+
+# $1: governor:w
+
+loop_gitsource()
+{
+ printf "\nGitsource total test times is $LOOP_TIMES for $1\n\n"
+ for i in `seq 1 $LOOP_TIMES`
+ do
+ run_gitsource $1 $i
+ parse_gitsource $1 $i
+ done
+}
+
+# $1: governor
+gather_gitsource()
+{
+ printf "Gitsource test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_GIT.result
+ printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_GIT.result
+
+ grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_GIT-des-perf-$1.log
+ avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-des-perf-$1.log)
+ printf "Gitsource-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result
+
+ grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_GIT-freq-$1.log
+ avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-freq-$1.log)
+ printf "Gitsource-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result
+
+ grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_GIT-load-$1.log
+ avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-load-$1.log)
+ printf "Gitsource-$1 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result
+
+ grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "user time(s):" | awk '{print $NF}' > $OUTFILE_GIT-time-$1.log
+ time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1.log)
+ printf "Gitsource-$1 total user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result
+
+ avg_time=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-time-$1.log)
+ printf "Gitsource-$1 avg user times(s): $avg_time\n" | tee -a $OUTFILE_GIT.result
+
+ grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_GIT-energy-$1.log
+ en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1.log)
+ printf "Gitsource-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
+
+ avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-energy-$1.log)
+ printf "Gitsource-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_GIT.result
+
+ ppw=`echo "scale=4;$avg_time/$avg_en" | bc | awk '{printf "%.4f", $0}'`
+ printf "Gitsource-$1 PPW(s/J): $ppw\n" | tee -a $OUTFILE_GIT.result
+ printf "\n" | tee -a $OUTFILE_GIT.result
+
+ store_csv_gitsource $1 "Average" $avg_des_perf $avg_freq $avg_load $avg_time $avg_en $ppw
+ empty_line_csv_gitsource
+}
+
+amd_pstate_gitsource()
+{
+ printf "\n---------------------------------------------\n"
+ printf "*** Running AMD P-state gitsource ***"
+ printf "\n---------------------------------------------\n"
+
+ pre_clear_gitsource
+
+ install_gitsource
+
+ store_csv_gitsource "Governor" "Round" "Des-perf" "Freq" "Load" "Time(s)" "Energy(Joules)" "PPW(s/J)"
+
+ for_each_policy backup_governor
+
+ for governor in ${gitsource_governors[*]} ; do
+ printf "\nSpecified governor is $governor\n\n"
+ for_each_policy switch_governor $governor
+ loop_gitsource $governor
+ gather_gitsource $governor
+ done
+
+ restore_governor
+
+ post_clear_gitsource
+}
diff --git a/tools/testing/selftests/amd-pstate/main.sh b/tools/testing/selftests/amd-pstate/main.sh
index ae71fe62e3b0..69bf8ea371a5 100755
--- a/tools/testing/selftests/amd-pstate/main.sh
+++ b/tools/testing/selftests/amd-pstate/main.sh
@@ -10,6 +10,7 @@ fi
source basic.sh
source tbench.sh
+source 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/')
@@ -18,6 +19,7 @@ VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}')
FUNC=all
OUTFILE=selftest
OUTFILE_TBENCH="$OUTFILE.tbench"
+OUTFILE_GIT="$OUTFILE.gitsource"
SYSFS=
CPUROOT=
@@ -126,6 +128,9 @@ amd_pstate_all()
# tbench
amd_pstate_tbench
+
+ # gitsource
+ amd_pstate_gitsource
}
helpme()
@@ -135,7 +140,8 @@ helpme()
[-o <output-file-for-dump>]
[-c <all: All testing,
basic: Basic testing,
- tbench: Tbench testing.>]
+ tbench: Tbench testing,
+ gitsource: Gitsource testing.>]
[-t <tbench time limit>]
[-p <tbench process number>]
[-l <loop times for tbench]
@@ -153,7 +159,7 @@ parse_arguments()
helpme
;;
- c) # --func_type (Function to perform: basic, tbench (default: all))
+ c) # --func_type (Function to perform: basic, tbench, gitsource (default: all))
FUNC=$OPTARG
;;
@@ -169,7 +175,7 @@ parse_arguments()
PROCESS_NUM=$OPTARG
;;
- l) # --tbench-loop-times
+ l) # --tbench/gitsource-loop-times
LOOP_TIMES=$OPTARG
;;
@@ -259,6 +265,10 @@ do_test()
amd_pstate_tbench
;;
+ "gitsource")
+ amd_pstate_gitsource
+ ;;
+
*)
echo "Invalid [-f] function type"
helpme
@@ -283,6 +293,11 @@ pre_clear_dumps()
rm -rf $OUTFILE_TBENCH*
;;
+ "gitsource")
+ rm -rf $OUTFILE.log
+ rm -rf $OUTFILE.backup_governor.log
+ rm -rf $OUTFILE_GIT*
+ ;;
esac
}
--
2.25.1
Modify amd-pstate-ut.sh to basic.sh.
The purpose of this modification is to facilitate the subsequent
addition of gitsource, tbench and other tests.
Signed-off-by: Meng Li <[email protected]>
---
tools/testing/selftests/amd-pstate/Makefile | 3 +-
.../selftests/amd-pstate/amd-pstate-ut.sh | 55 --------
tools/testing/selftests/amd-pstate/basic.sh | 38 +++++
tools/testing/selftests/amd-pstate/main.sh | 131 ++++++++++++++++++
tools/testing/selftests/amd-pstate/run.sh | 15 ++
5 files changed, 186 insertions(+), 56 deletions(-)
delete mode 100755 tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
create mode 100755 tools/testing/selftests/amd-pstate/basic.sh
create mode 100755 tools/testing/selftests/amd-pstate/main.sh
create mode 100755 tools/testing/selftests/amd-pstate/run.sh
diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
index 199867f44b32..167ab51ec290 100644
--- a/tools/testing/selftests/amd-pstate/Makefile
+++ b/tools/testing/selftests/amd-pstate/Makefile
@@ -4,6 +4,7 @@
# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
all:
-TEST_PROGS := amd-pstate-ut.sh
+TEST_PROGS := run.sh
+TEST_FILES := main.sh basic.sh
include ../lib.mk
diff --git a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh b/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
deleted file mode 100755
index 273364650285..000000000000
--- a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-# amd-pstate-ut is a test module for testing the amd-pstate driver.
-# It can only run on x86 architectures and current cpufreq driver
-# must be amd-pstate.
-# (1) It can help all users to verify their processor support
-# (SBIOS/Firmware or Hardware).
-# (2) Kernel can have a basic function test to avoid the kernel
-# regression during the update.
-# (3) We can introduce more functional or performance tests to align
-# the result together, it will benefit power and performance scale optimization.
-
-# Kselftest framework requirement - SKIP code is 4.
-ksft_skip=4
-
-# 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}')
-
-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 [ "$scaling_driver" != "amd-pstate" ]; then
- echo "$0 # Skipped: Test can only run on amd-pstate driver."
- echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
- exit $ksft_skip
-fi
-
-msg="Skip all tests:"
-if [ ! -w /dev ]; then
- echo $msg please run this as root >&2
- exit $ksft_skip
-fi
-
-if ! /sbin/modprobe -q -n amd-pstate-ut; then
- echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]"
- exit $ksft_skip
-fi
-if /sbin/modprobe -q amd-pstate-ut; then
- /sbin/modprobe -q -r amd-pstate-ut
- echo "amd-pstate-ut: ok"
-else
- echo "amd-pstate-ut: [FAIL]"
- exit 1
-fi
diff --git a/tools/testing/selftests/amd-pstate/basic.sh b/tools/testing/selftests/amd-pstate/basic.sh
new file mode 100755
index 000000000000..e4c43193e4a3
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/basic.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+# amd-pstate-ut is a test module for testing the amd-pstate driver.
+# It can only run on x86 architectures and current cpufreq driver
+# must be amd-pstate.
+# (1) It can help all users to verify their processor support
+# (SBIOS/Firmware or Hardware).
+# (2) Kernel can have a basic function test to avoid the kernel
+# regression during the update.
+# (3) We can introduce more functional or performance tests to align
+# the result together, it will benefit power and performance scale optimization.
+
+# protect against multiple inclusion
+if [ $FILE_BASIC ]; then
+ return 0
+else
+ FILE_BASIC=DONE
+fi
+
+amd_pstate_basic()
+{
+ printf "\n---------------------------------------------\n"
+ printf "*** Running AMD P-state ut ***"
+ printf "\n---------------------------------------------\n"
+
+ if ! /sbin/modprobe -q -n amd-pstate-ut; then
+ echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]"
+ exit $ksft_skip
+ fi
+ if /sbin/modprobe -q amd-pstate-ut; then
+ /sbin/modprobe -q -r amd-pstate-ut
+ echo "amd-pstate-basic: ok"
+ else
+ echo "amd-pstate-basic: [FAIL]"
+ exit 1
+ fi
+}
diff --git a/tools/testing/selftests/amd-pstate/main.sh b/tools/testing/selftests/amd-pstate/main.sh
new file mode 100755
index 000000000000..1c28b5d7b4c5
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/main.sh
@@ -0,0 +1,131 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# protect against multiple inclusion
+if [ $FILE_MAIN ]; then
+ return 0
+else
+ FILE_MAIN=DONE
+fi
+
+source basic.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}')
+
+FUNC=all
+OUTFILE=selftest
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+
+# All amd-pstate tests
+amd_pstate_all()
+{
+ printf "\n=============================================\n"
+ printf "***** Running AMD P-state Sanity Tests *****\n"
+ printf "=============================================\n\n"
+
+ # unit test for amd-pstate kernel driver
+ amd_pstate_basic
+}
+
+helpme()
+{
+ printf "Usage: $0 [OPTION...]
+ [-h <help>]
+ [-o <output-file-for-dump>]
+ [-c <all: All testing,
+ basic: Basic testing.>]
+ \n"
+ exit 2
+}
+
+parse_arguments()
+{
+ while getopts ho:c: arg
+ do
+ case $arg in
+ h) # --help
+ helpme
+ ;;
+
+ c) # --func_type (Function to perform: basic (default: all))
+ FUNC=$OPTARG
+ ;;
+
+ o) # --output-file (Output file to store dumps)
+ OUTFILE=$OPTARG
+ ;;
+
+ \?)
+ helpme
+ ;;
+ esac
+ done
+}
+
+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 [ "$scaling_driver" != "amd-pstate" ]; then
+ echo "$0 # Skipped: Test can only run on amd-pstate driver."
+ echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
+ exit $ksft_skip
+ fi
+
+ msg="Skip all tests:"
+ if [ ! -w /dev ]; then
+ echo $msg please run this as root >&2
+ exit $ksft_skip
+ fi
+}
+
+do_test()
+{
+ case "$FUNC" in
+ "all")
+ amd_pstate_all
+ ;;
+
+ "basic")
+ amd_pstate_basic
+ ;;
+
+ *)
+ echo "Invalid [-f] function type"
+ helpme
+ ;;
+ esac
+}
+
+# clear dumps
+pre_clear_dumps()
+{
+ case "$FUNC" in
+ "all")
+ rm -rf $OUTFILE*
+ ;;
+
+ "basic")
+ ;;
+
+ esac
+}
+
+post_clear_dumps()
+{
+ rm -rf $OUTFILE.log
+}
diff --git a/tools/testing/selftests/amd-pstate/run.sh b/tools/testing/selftests/amd-pstate/run.sh
new file mode 100755
index 000000000000..247e80bfee44
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/run.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+source main.sh
+
+# 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
--
2.25.1
Add tbench.sh trigger the tbench testing and monitor the cpu desire
performance, frequency, load, power consumption and throughput etc.
Signed-off-by: Meng Li <[email protected]>
---
tools/testing/selftests/amd-pstate/Makefile | 10 +-
tools/testing/selftests/amd-pstate/main.sh | 168 ++++++++++++++++-
tools/testing/selftests/amd-pstate/tbench.sh | 187 +++++++++++++++++++
3 files changed, 361 insertions(+), 4 deletions(-)
create mode 100755 tools/testing/selftests/amd-pstate/tbench.sh
diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
index 167ab51ec290..e2fb03381a32 100644
--- a/tools/testing/selftests/amd-pstate/Makefile
+++ b/tools/testing/selftests/amd-pstate/Makefile
@@ -4,7 +4,15 @@
# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
all:
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq (x86,$(ARCH))
+TEST_GEN_FILES += ../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py
+TEST_GEN_FILES += ../../../power/x86/intel_pstate_tracer/intel_pstate_tracer.py
+endif
+
TEST_PROGS := run.sh
-TEST_FILES := main.sh basic.sh
+TEST_FILES := main.sh basic.sh tbench.sh
include ../lib.mk
diff --git a/tools/testing/selftests/amd-pstate/main.sh b/tools/testing/selftests/amd-pstate/main.sh
index 1c28b5d7b4c5..ae71fe62e3b0 100755
--- a/tools/testing/selftests/amd-pstate/main.sh
+++ b/tools/testing/selftests/amd-pstate/main.sh
@@ -9,6 +9,7 @@ else
fi
source basic.sh
+source tbench.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/')
@@ -16,10 +17,95 @@ VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}')
FUNC=all
OUTFILE=selftest
+OUTFILE_TBENCH="$OUTFILE.tbench"
+
+SYSFS=
+CPUROOT=
+CPUFREQROOT=
+MAKE_CPUS=
+
+TIME_LIMIT=100
+PROCESS_NUM=128
+LOOP_TIMES=3
+TRACER_INTERVAL=10
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
+# 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
+}
+
+# $1: policy
+backup_governor()
+{
+ local cur_gov=$(find_current_governor $1)
+
+ printf "Governor backup done for $1: $cur_gov\n"
+ echo "$1 $cur_gov" >> $OUTFILE.backup_governor.log
+}
+
+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
+ _switch_governor $policy $governor
+ printf "Governor restored for $policy to $governor\n"
+ done
+}
+
+# $1: policy, $2: governor
+_switch_governor()
+{
+ echo $2 > $CPUFREQROOT/$1/scaling_governor
+}
+
+for_each_policy()
+{
+ policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
+ for policy in $policies; do
+ $@ $policy
+ done
+}
+
+# $1: governor, $2: policy
+switch_governor()
+{
+ local filepath=$CPUFREQROOT/$2/scaling_available_governors
+
+ # Exit if cpu isn't managed by cpufreq core
+ if [ ! -f $filepath ]; then
+ return;
+ fi
+
+ # switch governor
+ _switch_governor $2 $1
+
+ printf "Switched governor for $2 to $1\n"
+}
+
# All amd-pstate tests
amd_pstate_all()
{
@@ -27,8 +113,19 @@ amd_pstate_all()
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
}
helpme()
@@ -37,21 +134,26 @@ helpme()
[-h <help>]
[-o <output-file-for-dump>]
[-c <all: All testing,
- basic: Basic testing.>]
+ basic: Basic testing,
+ tbench: Tbench testing.>]
+ [-t <tbench time limit>]
+ [-p <tbench process number>]
+ [-l <loop times for tbench]
+ [-i <amd tracer interval]
\n"
exit 2
}
parse_arguments()
{
- while getopts ho:c: arg
+ while getopts ho:c:t:p:l:i: arg
do
case $arg in
h) # --help
helpme
;;
- c) # --func_type (Function to perform: basic (default: all))
+ c) # --func_type (Function to perform: basic, tbench (default: all))
FUNC=$OPTARG
;;
@@ -59,6 +161,21 @@ parse_arguments()
OUTFILE=$OPTARG
;;
+ t) # --tbench-time-limit
+ TIME_LIMIT=$OPTARG
+ ;;
+
+ p) # --tbench-process-number
+ PROCESS_NUM=$OPTARG
+ ;;
+
+ l) # --tbench-loop-times
+ LOOP_TIMES=$OPTARG
+ ;;
+
+ i) # --amd-tracer-interval
+ TRACER_INTERVAL=$OPTARG
+ ;;
\?)
helpme
;;
@@ -91,10 +208,44 @@ prerequisite()
echo $msg please run this as root >&2
exit $ksft_skip
fi
+
+ if [ ! -f perf ] ; then
+ echo $msg please build perf under directory tools/perf and copy it to directory amd-pstate. >&2
+ exit $ksft_skip
+ fi
+
+ 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
@@ -104,6 +255,10 @@ do_test()
amd_pstate_basic
;;
+ "tbench")
+ amd_pstate_tbench
+ ;;
+
*)
echo "Invalid [-f] function type"
helpme
@@ -122,10 +277,17 @@ pre_clear_dumps()
"basic")
;;
+ "tbench")
+ rm -rf $OUTFILE.log
+ rm -rf $OUTFILE.backup_governor.log
+ rm -rf $OUTFILE_TBENCH*
+ ;;
+
esac
}
post_clear_dumps()
{
rm -rf $OUTFILE.log
+ rm -rf $OUTFILE.backup_governor.log
}
diff --git a/tools/testing/selftests/amd-pstate/tbench.sh b/tools/testing/selftests/amd-pstate/tbench.sh
new file mode 100755
index 000000000000..0320300971ce
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/tbench.sh
@@ -0,0 +1,187 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+# Testing and monitor the cpu frequency and performance when
+# this script trigger tbench test.
+
+# protect against multiple inclusion
+if [ $FILE_TBENCH ]; then
+ return 0
+else
+ FILE_TBENCH=DONE
+fi
+
+tbench_name="dbench-4.0"
+tbench_tar="$tbench_name.tar.gz"
+tbench_url="https://ftp.samba.org/pub/pub/tridge/dbench/dbench-4.0.tar.gz"
+tbench_governors=("ondemand" "schedutil")
+
+# $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: performance, $7: energy, $8: PPW
+store_csv_tbench()
+{
+ echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_TBENCH.csv > /dev/null 2>&1
+}
+
+empty_line_csv_tbench()
+{
+ echo "" | tee -a $OUTFILE_TBENCH.csv > /dev/null 2>&1
+}
+
+pre_clear_tbench()
+{
+ rm -rf results/tracer-tbench*
+}
+
+post_clear_tbench()
+{
+ rm -rf results/tracer-tbench*
+ rm -rf $OUTFILE_TBENCH*.log
+}
+
+install_tbench()
+{
+ if [ ! -d $tbench_name ]; then
+ printf "Download tbench, please wait a moment ...\n\n"
+ wget -O $tbench_tar $tbench_url > /dev/null 2>&1
+
+ printf "Tar tbench ...\n\n"
+ tar -xzf $tbench_tar
+
+ printf "Compile and install tbench ...\n\n"
+ cd $tbench_name
+ ./autogen.sh
+ ./configure > /dev/null 2>&1
+ make > /dev/null 2>&1
+ make install > /dev/null 2>&1
+ cd ..
+ fi
+}
+
+# $1: governor, $2: loop
+run_tbench()
+{
+ echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
+ ./amd_pstate_trace.py -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
+
+ printf "Test tbench for $1 #$2 time_limit: $TIME_LIMIT procs_num: $PROCESS_NUM\n"
+ cd $tbench_name
+ ./tbench_srv > /dev/null 2>&1 &
+ ./../perf stat -a --per-socket -I 1000 -e power/energy-pkg/ ./tbench -t $TIME_LIMIT $PROCESS_NUM > ../$OUTFILE_TBENCH-perf-$1-$2.log 2>&1
+ cd ..
+
+ pid=`pidof tbench_srv`
+ kill $pid
+
+ for job in `jobs -p`
+ do
+ echo "Waiting for job id $job"
+ wait $job
+ done
+}
+
+# $1: governor, $2: loop
+parse_tbench()
+{
+ awk '{print $5}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-des-perf-$1-$2.log
+ avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-des-perf-$1-$2.log)
+ printf "Tbench-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result
+
+ awk '{print $7}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-freq-$1-$2.log
+ avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-freq-$1-$2.log)
+ printf "Tbench-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result
+
+ awk '{print $11}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-load-$1-$2.log
+ avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-load-$1-$2.log)
+ printf "Tbench-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result
+
+ grep Throughput $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $2}' > $OUTFILE_TBENCH-throughput-$1-$2.log
+ tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1-$2.log)
+ printf "Tbench-$1-#$2 throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result
+
+ grep Joules $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_TBENCH-energy-$1-$2.log
+ en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1-$2.log)
+ printf "Tbench-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result
+
+ ppw=`echo "scale=4;($TIME_LIMIT-1)*$tp_sum/$en_sum" | bc | awk '{printf "%.4f", $0}'`
+ printf "Tbench-$1-#$2 PPW(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result
+ printf "\n" | tee -a $OUTFILE_TBENCH.result
+
+ store_csv_tbench $1 $2 $avg_des_perf $avg_freq $avg_load $tp_sum $en_sum $ppw
+}
+
+# $1: governor
+loop_tbench()
+{
+ printf "\nTbench total test times is $LOOP_TIMES for $1\n\n"
+ for i in `seq 1 $LOOP_TIMES`
+ do
+ run_tbench $1 $i
+ parse_tbench $1 $i
+ done
+}
+
+# $1: governor
+gather_tbench()
+{
+ printf "Tbench test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_TBENCH.result
+ printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_TBENCH.result
+
+ grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_TBENCH-des-perf-$1.log
+ avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-des-perf-$1.log)
+ printf "Tbench-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result
+
+ grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_TBENCH-freq-$1.log
+ avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-freq-$1.log)
+ printf "Tbench-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result
+
+ grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_TBENCH-load-$1.log
+ avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-load-$1.log)
+ printf "Tbench-$1 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result
+
+ grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "throughput(MB/s):" | awk '{print $NF}' > $OUTFILE_TBENCH-throughput-$1.log
+ tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1.log)
+ printf "Tbench-$1 total throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result
+
+ avg_tp=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-throughput-$1.log)
+ printf "Tbench-$1 avg throughput(MB/s): $avg_tp\n" | tee -a $OUTFILE_TBENCH.result
+
+ grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_TBENCH-energy-$1.log
+ en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1.log)
+ printf "Tbench-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result
+
+ avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-energy-$1.log)
+ printf "Tbench-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_TBENCH.result
+
+ ppw=`echo "scale=4;($TIME_LIMIT-1)*$avg_tp/$avg_en" | bc | awk '{printf "%.4f", $0}'`
+ printf "Tbench-$1 PPW(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result
+ printf "\n" | tee -a $OUTFILE_TBENCH.result
+
+ store_csv_tbench $1 "Average" $avg_des_perf $avg_freq $avg_load $avg_tp $avg_en $ppw
+ empty_line_csv_tbench
+}
+
+amd_pstate_tbench()
+{
+ printf "\n---------------------------------------------\n"
+ printf "*** Running AMD P-state tbench ***"
+ printf "\n---------------------------------------------\n"
+
+ pre_clear_tbench
+
+ install_tbench
+
+ store_csv_tbench "Governor" "Round" "Des-perf" "Freq" "Load" "Performance(MB/s)" "Energy(Joules)" "PPW(MB/J)"
+
+ for_each_policy backup_governor
+
+ for governor in ${tbench_governors[*]} ; do
+ printf "\nSpecified governor is $governor\n\n"
+ for_each_policy switch_governor $governor
+ loop_tbench $governor
+ gather_tbench $governor
+ done
+
+ restore_governor
+
+ post_clear_tbench
+}
--
2.25.1
On Wed, Jul 06, 2022 at 03:36:22PM +0800, Meng, Li (Jassmine) wrote:
> Introduce tbench and gitsource test cases design and implementation.
> Monitor cpus changes about performance and power consumption etc.
>
> Signed-off-by: Meng Li <[email protected]>
> ---
> Documentation/admin-guide/pm/amd-pstate.rst | 124 +++++++++++++++++---
> 1 file changed, 106 insertions(+), 18 deletions(-)
>
> diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
> index 8f3d30c5a0d8..48fb488e000e 100644
> --- a/Documentation/admin-guide/pm/amd-pstate.rst
> +++ b/Documentation/admin-guide/pm/amd-pstate.rst
> @@ -409,37 +409,53 @@ Unit Tests for amd-pstate
>
> 1. Test case decriptions
>
> + 1). basic tests
> +
> + Test prerequisite and basic functions for the ``amd-pstate`` driver.
> +
> +---------+--------------------------------+------------------------------------------------------------------------------------+
> | Index | Functions | Description |
> +=========+================================+====================================================================================+
> - | 0 | amd_pstate_ut_acpi_cpc_valid || Check whether the _CPC object is present in SBIOS. |
> + | 1 | amd_pstate_ut_acpi_cpc_valid || Check whether the _CPC object is present in SBIOS. |
> | | || |
> | | || The detail refer to `Processor Support <processor_support_>`_. |
> +---------+--------------------------------+------------------------------------------------------------------------------------+
> - | 1 | amd_pstate_ut_check_enabled || Check whether AMD P-State is enabled. |
> + | 2 | amd_pstate_ut_check_enabled || Check whether AMD P-State is enabled. |
> | | || |
> | | || AMD P-States and ACPI hardware P-States always can be supported in one processor. |
> | | | But AMD P-States has the higher priority and if it is enabled with |
> | | | :c:macro:`MSR_AMD_CPPC_ENABLE` or ``cppc_set_enable``, it will respond to the |
> | | | request from AMD P-States. |
> +---------+--------------------------------+------------------------------------------------------------------------------------+
> - | 2 | amd_pstate_ut_check_perf || Check if the each performance values are reasonable. |
> + | 3 | amd_pstate_ut_check_perf || Check if the each performance values are reasonable. |
> | | || highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0. |
> +---------+--------------------------------+------------------------------------------------------------------------------------+
> - | 3 | amd_pstate_ut_check_freq || Check if the each frequency values and max freq when set support boost mode |
> + | 4 | amd_pstate_ut_check_freq || Check if the each frequency values and max freq when set support boost mode |
> | | | are reasonable. |
> | | || max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0 |
> | | || If boost is not active but supported, this maximum frequency will be larger than |
> | | | the one in ``cpuinfo``. |
> +---------+--------------------------------+------------------------------------------------------------------------------------+
>
> + 2). Tbench test
> +
> + Testing and monitor the cpu changes when running tbench benchmark under the specified governor.
Test and monior ...
> + These changes include desire performance, frequency, load, performance, energy etc.
> + The specified governor is ondemand or schedutil.
> +
> + 3). Gitsource test
> +
> + Testing and monitor the cpu changes when running gitsource benchmark under the specified governor.
> + These changes include desire performance, frequency, load, time, energy etc.
> + The specified governor is ondemand or schedutil.
Test and monior ...
> +
> #. How to execute the tests
>
> We use test module in the kselftest frameworks to implement it.
> We create amd-pstate-ut module and tie it into kselftest.(for
> details refer to Linux Kernel Selftests [4]_).
>
> - 1. Build
> + a. Build
Why do you update the 1 -> a here?
>
> + open the :c:macro:`CONFIG_X86_AMD_PSTATE` configuration option.
> + set the :c:macro:`CONFIG_X86_AMD_PSTATE_UT` configuration option to M.
> @@ -449,23 +465,95 @@ Unit Tests for amd-pstate
> $ cd linux
> $ make -C tools/testing/selftests
>
> + + make perf ::
> +
> + $ cd tools/perf/
> + $ make
> +
> +
> #. Installation & Steps ::
>
> $ make -C tools/testing/selftests install INSTALL_PATH=~/kselftest
> + $ cp tools/perf/perf ~/kselftest/amd-pstate/
> $ sudo ./kselftest/run_kselftest.sh -c amd-pstate
> - TAP version 13
> - 1..1
> - # selftests: amd-pstate: amd-pstate-ut.sh
> - # amd-pstate-ut: ok
> - ok 1 selftests: amd-pstate: amd-pstate-ut.sh
> -
> - #. Results ::
> -
> - $ dmesg | grep "amd_pstate_ut" | tee log.txt
> - [12977.570663] amd_pstate_ut: 1 amd_pstate_ut_acpi_cpc_valid success!
> - [12977.570673] amd_pstate_ut: 2 amd_pstate_ut_check_enabled success!
> - [12977.571207] amd_pstate_ut: 3 amd_pstate_ut_check_perf success!
> - [12977.571212] amd_pstate_ut: 4 amd_pstate_ut_check_freq success!
> +
> + #. Specified test case ::
> +
> + $ cd ~/kselftest/amd-pstate
> + $ sudo ./run.sh -t basic
> + $ sudo ./run.sh -t tbench
> + $ sudo ./run.sh -t gitsource
> + $ ./run.sh --help
> + ./run.sh: illegal option -- -
> + Usage: ./run.sh [OPTION...]
> + [-h <help>]
> + [-o <output-file-for-dump>]
> + [-t <all: All testing,
> + basic: Basic testing,
> + tbench: Test tbench,
> + gitsource: Test gitsource.>]
> + [-i <tbench time limit>]
> + [-p <tbench process number>]
> + [-l <loop times for tbench/gitsource]
> + [-n <amd tracer interval]
> +
> + 4). Results
4) -> #.?
We would like to align all the number format in the paragraph like below:
1.
1)
2)
3)
2.
1)
2)
...
Thanks,
Ray
> +
> + + basic
> +
> + When you finish test, you will get the following log info ::
> +
> + $ dmesg | grep "amd_pstate_ut" | tee log.txt
> + [12977.570663] amd_pstate_ut: 1 amd_pstate_ut_acpi_cpc_valid success!
> + [12977.570673] amd_pstate_ut: 2 amd_pstate_ut_check_enabled success!
> + [12977.571207] amd_pstate_ut: 3 amd_pstate_ut_check_perf success!
> + [12977.571212] amd_pstate_ut: 4 amd_pstate_ut_check_freq success!
> +
> + + tbench
> +
> + When you finish test, you will get selftest.tbench.csv and selftest.tbench.result files form amd-pstate.
> + Open selftest.tbench.csv :
> +
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> + + Governor | Round | Des-perf | Freq | Load | Performance(MB/s) | Energy(Joules) | PPW(MB/J) |
> + +===========+=========+==========+=========+==========+===================+================+===========+
> + + ondemand | 1 | 203.244 | 3.2225 | 87.5064 | 35368.2 | 6626.1 | 101.4164 |
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> + + ondemand | 2 | 205.861 | 3.24948 | 88.9281 | 34795.7 | 6547.06 | 100.9794 |
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> + + ondemand | Average | 204.553 | 3.23599 | 88.2173 | 35081.9 | 6586.58 | 101.1991 |
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> + + | | | | | | | |
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> + + schedutil | 1 | 253.735 | 3.26755 | 96.6481 | 34653.9 | 6622.85 | 99.4170 |
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> + + schedutil | 2 | 254.654 | 3.44086 | 92.3564 | 31707.8 | 6573.67 | 91.6456 |
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> + + schedutil | Average | 254.195 | 3.3542 | 94.5023 | 33180.8 | 6598.26 | 95.5456 |
> + +-----------+---------+----------+---------+----------+-------------------+----------------+-----------+
> +
> + + gitsource
> +
> + When you finish test, you will get selftest.gitsource.csv and selftest.gitsource.result files form amd-pstate.
> + Open selftest.gitsource.csv :
> +
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
> + + Governor | Round | Des-perf | Freq | Load | Times(s) | Energy(Joules) | PPW(s/J) |
> + +===========+=========+==========+==========+==========+==========+================+==========+
> + + ondemand | 1 | 29.7305 | 1.13025 | 8.49585 | 341.61 | 6811.02 | 0.0501 |
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
> + + ondemand | 2 | 28.0523 | 1.33848 | 8.16496 | 339.21 | 6999.84 | 0.0484 |
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
> + + ondemand | Average | 28.8914 | 1.23436 | 8.33041 | 340.41 | 6905.43 | 0.0492 |
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
> + + | | | | | | | |
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
> + + schedutil | 1 | 29.6971 | 0.834149 | 9.57879 | 278.15 | 5992.26 | 0.0464 |
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
> + + schedutil | 2 | 31.6573 | 0.99686 | 8.60513 | 280.28 | 5772.59 | 0.0485 |
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
> + + schedutil | Average | 30.6772 | 0.915504 | 9.09196 | 279.215 | 5882.43 | 0.0474 |
> + +-----------+---------+----------+----------+----------+----------+----------------+----------+
>
> Reference
> ===========
> --
> 2.25.1
>
On Wed, Jul 06, 2022 at 03:36:19PM +0800, Meng, Li (Jassmine) wrote:
> Modify amd-pstate-ut.sh to basic.sh.
> The purpose of this modification is to facilitate the subsequent
> addition of gitsource, tbench and other tests.
>
> Signed-off-by: Meng Li <[email protected]>
Since amd-pstate-ut.sh is separated by three scripts below, could you
please describe how to use them in the commit log?
Thanks,
Ray
> ---
> tools/testing/selftests/amd-pstate/Makefile | 3 +-
> .../selftests/amd-pstate/amd-pstate-ut.sh | 55 --------
> tools/testing/selftests/amd-pstate/basic.sh | 38 +++++
> tools/testing/selftests/amd-pstate/main.sh | 131 ++++++++++++++++++
> tools/testing/selftests/amd-pstate/run.sh | 15 ++
> 5 files changed, 186 insertions(+), 56 deletions(-)
> delete mode 100755 tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> create mode 100755 tools/testing/selftests/amd-pstate/basic.sh
> create mode 100755 tools/testing/selftests/amd-pstate/main.sh
> create mode 100755 tools/testing/selftests/amd-pstate/run.sh
>
> diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
> index 199867f44b32..167ab51ec290 100644
> --- a/tools/testing/selftests/amd-pstate/Makefile
> +++ b/tools/testing/selftests/amd-pstate/Makefile
> @@ -4,6 +4,7 @@
> # No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
> all:
>
> -TEST_PROGS := amd-pstate-ut.sh
> +TEST_PROGS := run.sh
> +TEST_FILES := main.sh basic.sh
>
> include ../lib.mk
> diff --git a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh b/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> deleted file mode 100755
> index 273364650285..000000000000
> --- a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -#!/bin/sh
> -# SPDX-License-Identifier: GPL-2.0
> -
> -# amd-pstate-ut is a test module for testing the amd-pstate driver.
> -# It can only run on x86 architectures and current cpufreq driver
> -# must be amd-pstate.
> -# (1) It can help all users to verify their processor support
> -# (SBIOS/Firmware or Hardware).
> -# (2) Kernel can have a basic function test to avoid the kernel
> -# regression during the update.
> -# (3) We can introduce more functional or performance tests to align
> -# the result together, it will benefit power and performance scale optimization.
> -
> -# Kselftest framework requirement - SKIP code is 4.
> -ksft_skip=4
> -
> -# 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}')
> -
> -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 [ "$scaling_driver" != "amd-pstate" ]; then
> - echo "$0 # Skipped: Test can only run on amd-pstate driver."
> - echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
> - exit $ksft_skip
> -fi
> -
> -msg="Skip all tests:"
> -if [ ! -w /dev ]; then
> - echo $msg please run this as root >&2
> - exit $ksft_skip
> -fi
> -
> -if ! /sbin/modprobe -q -n amd-pstate-ut; then
> - echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]"
> - exit $ksft_skip
> -fi
> -if /sbin/modprobe -q amd-pstate-ut; then
> - /sbin/modprobe -q -r amd-pstate-ut
> - echo "amd-pstate-ut: ok"
> -else
> - echo "amd-pstate-ut: [FAIL]"
> - exit 1
> -fi
> diff --git a/tools/testing/selftests/amd-pstate/basic.sh b/tools/testing/selftests/amd-pstate/basic.sh
> new file mode 100755
> index 000000000000..e4c43193e4a3
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/basic.sh
> @@ -0,0 +1,38 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# amd-pstate-ut is a test module for testing the amd-pstate driver.
> +# It can only run on x86 architectures and current cpufreq driver
> +# must be amd-pstate.
> +# (1) It can help all users to verify their processor support
> +# (SBIOS/Firmware or Hardware).
> +# (2) Kernel can have a basic function test to avoid the kernel
> +# regression during the update.
> +# (3) We can introduce more functional or performance tests to align
> +# the result together, it will benefit power and performance scale optimization.
> +
> +# protect against multiple inclusion
> +if [ $FILE_BASIC ]; then
> + return 0
> +else
> + FILE_BASIC=DONE
> +fi
> +
> +amd_pstate_basic()
> +{
> + printf "\n---------------------------------------------\n"
> + printf "*** Running AMD P-state ut ***"
> + printf "\n---------------------------------------------\n"
> +
> + if ! /sbin/modprobe -q -n amd-pstate-ut; then
> + echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]"
> + exit $ksft_skip
> + fi
> + if /sbin/modprobe -q amd-pstate-ut; then
> + /sbin/modprobe -q -r amd-pstate-ut
> + echo "amd-pstate-basic: ok"
> + else
> + echo "amd-pstate-basic: [FAIL]"
> + exit 1
> + fi
> +}
> diff --git a/tools/testing/selftests/amd-pstate/main.sh b/tools/testing/selftests/amd-pstate/main.sh
> new file mode 100755
> index 000000000000..1c28b5d7b4c5
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/main.sh
> @@ -0,0 +1,131 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# protect against multiple inclusion
> +if [ $FILE_MAIN ]; then
> + return 0
> +else
> + FILE_MAIN=DONE
> +fi
> +
> +source basic.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}')
> +
> +FUNC=all
> +OUTFILE=selftest
> +
> +# Kselftest framework requirement - SKIP code is 4.
> +ksft_skip=4
> +
> +# All amd-pstate tests
> +amd_pstate_all()
> +{
> + printf "\n=============================================\n"
> + printf "***** Running AMD P-state Sanity Tests *****\n"
> + printf "=============================================\n\n"
> +
> + # unit test for amd-pstate kernel driver
> + amd_pstate_basic
> +}
> +
> +helpme()
> +{
> + printf "Usage: $0 [OPTION...]
> + [-h <help>]
> + [-o <output-file-for-dump>]
> + [-c <all: All testing,
> + basic: Basic testing.>]
> + \n"
> + exit 2
> +}
> +
> +parse_arguments()
> +{
> + while getopts ho:c: arg
> + do
> + case $arg in
> + h) # --help
> + helpme
> + ;;
> +
> + c) # --func_type (Function to perform: basic (default: all))
> + FUNC=$OPTARG
> + ;;
> +
> + o) # --output-file (Output file to store dumps)
> + OUTFILE=$OPTARG
> + ;;
> +
> + \?)
> + helpme
> + ;;
> + esac
> + done
> +}
> +
> +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 [ "$scaling_driver" != "amd-pstate" ]; then
> + echo "$0 # Skipped: Test can only run on amd-pstate driver."
> + echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
> + exit $ksft_skip
> + fi
> +
> + msg="Skip all tests:"
> + if [ ! -w /dev ]; then
> + echo $msg please run this as root >&2
> + exit $ksft_skip
> + fi
> +}
> +
> +do_test()
> +{
> + case "$FUNC" in
> + "all")
> + amd_pstate_all
> + ;;
> +
> + "basic")
> + amd_pstate_basic
> + ;;
> +
> + *)
> + echo "Invalid [-f] function type"
> + helpme
> + ;;
> + esac
> +}
> +
> +# clear dumps
> +pre_clear_dumps()
> +{
> + case "$FUNC" in
> + "all")
> + rm -rf $OUTFILE*
> + ;;
> +
> + "basic")
> + ;;
> +
> + esac
> +}
> +
> +post_clear_dumps()
> +{
> + rm -rf $OUTFILE.log
> +}
> diff --git a/tools/testing/selftests/amd-pstate/run.sh b/tools/testing/selftests/amd-pstate/run.sh
> new file mode 100755
> index 000000000000..247e80bfee44
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/run.sh
> @@ -0,0 +1,15 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +source main.sh
> +
> +# 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
> --
> 2.25.1
>
On Wed, Jul 06, 2022 at 03:36:20PM +0800, Meng, Li (Jassmine) wrote:
> Add tbench.sh trigger the tbench testing and monitor the cpu desire
> performance, frequency, load, power consumption and throughput etc.
>
> Signed-off-by: Meng Li <[email protected]>
> ---
> tools/testing/selftests/amd-pstate/Makefile | 10 +-
> tools/testing/selftests/amd-pstate/main.sh | 168 ++++++++++++++++-
> tools/testing/selftests/amd-pstate/tbench.sh | 187 +++++++++++++++++++
> 3 files changed, 361 insertions(+), 4 deletions(-)
> create mode 100755 tools/testing/selftests/amd-pstate/tbench.sh
>
> diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
> index 167ab51ec290..e2fb03381a32 100644
> --- a/tools/testing/selftests/amd-pstate/Makefile
> +++ b/tools/testing/selftests/amd-pstate/Makefile
> @@ -4,7 +4,15 @@
> # No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
> all:
>
> +uname_M := $(shell uname -m 2>/dev/null || echo not)
> +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
> +
> +ifeq (x86,$(ARCH))
> +TEST_GEN_FILES += ../../../power/x86/amd_pstate_tracer/amd_pstate_trace.py
> +TEST_GEN_FILES += ../../../power/x86/intel_pstate_tracer/intel_pstate_tracer.py
> +endif
> +
> TEST_PROGS := run.sh
> -TEST_FILES := main.sh basic.sh
> +TEST_FILES := main.sh basic.sh tbench.sh
>
> include ../lib.mk
> diff --git a/tools/testing/selftests/amd-pstate/main.sh b/tools/testing/selftests/amd-pstate/main.sh
> index 1c28b5d7b4c5..ae71fe62e3b0 100755
> --- a/tools/testing/selftests/amd-pstate/main.sh
> +++ b/tools/testing/selftests/amd-pstate/main.sh
> @@ -9,6 +9,7 @@ else
> fi
>
> source basic.sh
> +source tbench.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/')
> @@ -16,10 +17,95 @@ VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}')
>
> FUNC=all
> OUTFILE=selftest
> +OUTFILE_TBENCH="$OUTFILE.tbench"
> +
> +SYSFS=
> +CPUROOT=
> +CPUFREQROOT=
> +MAKE_CPUS=
> +
> +TIME_LIMIT=100
> +PROCESS_NUM=128
> +LOOP_TIMES=3
> +TRACER_INTERVAL=10
>
> # Kselftest framework requirement - SKIP code is 4.
> ksft_skip=4
>
> +# 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
> +}
> +
> +# $1: policy
> +backup_governor()
> +{
> + local cur_gov=$(find_current_governor $1)
> +
> + printf "Governor backup done for $1: $cur_gov\n"
> + echo "$1 $cur_gov" >> $OUTFILE.backup_governor.log
> +}
> +
> +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
> + _switch_governor $policy $governor
> + printf "Governor restored for $policy to $governor\n"
> + done
> +}
> +
> +# $1: policy, $2: governor
> +_switch_governor()
> +{
> + echo $2 > $CPUFREQROOT/$1/scaling_governor
> +}
> +
> +for_each_policy()
> +{
> + policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
> + for policy in $policies; do
> + $@ $policy
> + done
> +}
> +
> +# $1: governor, $2: policy
> +switch_governor()
> +{
> + local filepath=$CPUFREQROOT/$2/scaling_available_governors
> +
> + # Exit if cpu isn't managed by cpufreq core
> + if [ ! -f $filepath ]; then
> + return;
> + fi
> +
> + # switch governor
> + _switch_governor $2 $1
> +
> + printf "Switched governor for $2 to $1\n"
> +}
> +
> # All amd-pstate tests
> amd_pstate_all()
> {
> @@ -27,8 +113,19 @@ amd_pstate_all()
> 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
> }
>
> helpme()
> @@ -37,21 +134,26 @@ helpme()
> [-h <help>]
> [-o <output-file-for-dump>]
> [-c <all: All testing,
> - basic: Basic testing.>]
> + basic: Basic testing,
> + tbench: Tbench testing.>]
> + [-t <tbench time limit>]
> + [-p <tbench process number>]
> + [-l <loop times for tbench]
> + [-i <amd tracer interval]
> \n"
> exit 2
> }
>
> parse_arguments()
> {
> - while getopts ho:c: arg
> + while getopts ho:c:t:p:l:i: arg
> do
> case $arg in
> h) # --help
> helpme
> ;;
>
> - c) # --func_type (Function to perform: basic (default: all))
> + c) # --func_type (Function to perform: basic, tbench (default: all))
> FUNC=$OPTARG
> ;;
>
> @@ -59,6 +161,21 @@ parse_arguments()
> OUTFILE=$OPTARG
> ;;
>
> + t) # --tbench-time-limit
> + TIME_LIMIT=$OPTARG
> + ;;
> +
> + p) # --tbench-process-number
> + PROCESS_NUM=$OPTARG
> + ;;
> +
> + l) # --tbench-loop-times
> + LOOP_TIMES=$OPTARG
> + ;;
> +
> + i) # --amd-tracer-interval
> + TRACER_INTERVAL=$OPTARG
> + ;;
> \?)
> helpme
> ;;
> @@ -91,10 +208,44 @@ prerequisite()
> echo $msg please run this as root >&2
> exit $ksft_skip
> fi
> +
> + if [ ! -f perf ] ; then
> + echo $msg please build perf under directory tools/perf and copy it to directory amd-pstate. >&2
> + exit $ksft_skip
> + fi
> +
> + 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
> @@ -104,6 +255,10 @@ do_test()
> amd_pstate_basic
> ;;
>
> + "tbench")
> + amd_pstate_tbench
> + ;;
> +
> *)
> echo "Invalid [-f] function type"
> helpme
> @@ -122,10 +277,17 @@ pre_clear_dumps()
> "basic")
> ;;
>
> + "tbench")
> + rm -rf $OUTFILE.log
> + rm -rf $OUTFILE.backup_governor.log
> + rm -rf $OUTFILE_TBENCH*
> + ;;
> +
> esac
> }
>
> post_clear_dumps()
> {
> rm -rf $OUTFILE.log
> + rm -rf $OUTFILE.backup_governor.log
> }
> diff --git a/tools/testing/selftests/amd-pstate/tbench.sh b/tools/testing/selftests/amd-pstate/tbench.sh
> new file mode 100755
> index 000000000000..0320300971ce
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/tbench.sh
> @@ -0,0 +1,187 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# Testing and monitor the cpu frequency and performance when
> +# this script trigger tbench test.
> +
> +# protect against multiple inclusion
> +if [ $FILE_TBENCH ]; then
> + return 0
> +else
> + FILE_TBENCH=DONE
> +fi
> +
> +tbench_name="dbench-4.0"
> +tbench_tar="$tbench_name.tar.gz"
> +tbench_url="https://ftp.samba.org/pub/pub/tridge/dbench/dbench-4.0.tar.gz"
> +tbench_governors=("ondemand" "schedutil")
> +
> +# $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: performance, $7: energy, $8: PPW
> +store_csv_tbench()
> +{
> + echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_TBENCH.csv > /dev/null 2>&1
> +}
> +
> +empty_line_csv_tbench()
> +{
> + echo "" | tee -a $OUTFILE_TBENCH.csv > /dev/null 2>&1
> +}
> +
> +pre_clear_tbench()
> +{
> + rm -rf results/tracer-tbench*
> +}
> +
> +post_clear_tbench()
> +{
> + rm -rf results/tracer-tbench*
> + rm -rf $OUTFILE_TBENCH*.log
> +}
> +
> +install_tbench()
> +{
> + if [ ! -d $tbench_name ]; then
> + printf "Download tbench, please wait a moment ...\n\n"
> + wget -O $tbench_tar $tbench_url > /dev/null 2>&1
> +
> + printf "Tar tbench ...\n\n"
> + tar -xzf $tbench_tar
> +
> + printf "Compile and install tbench ...\n\n"
> + cd $tbench_name
> + ./autogen.sh
> + ./configure > /dev/null 2>&1
> + make > /dev/null 2>&1
> + make install > /dev/null 2>&1
> + cd ..
> + fi
> +}
> +
> +# $1: governor, $2: loop
> +run_tbench()
> +{
> + echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
> + ./amd_pstate_trace.py -n tracer-tbench-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1 &
> +
> + printf "Test tbench for $1 #$2 time_limit: $TIME_LIMIT procs_num: $PROCESS_NUM\n"
> + cd $tbench_name
> + ./tbench_srv > /dev/null 2>&1 &
> + ./../perf stat -a --per-socket -I 1000 -e power/energy-pkg/ ./tbench -t $TIME_LIMIT $PROCESS_NUM > ../$OUTFILE_TBENCH-perf-$1-$2.log 2>&1
> + cd ..
> +
> + pid=`pidof tbench_srv`
> + kill $pid
> +
> + for job in `jobs -p`
> + do
> + echo "Waiting for job id $job"
> + wait $job
> + done
> +}
> +
> +# $1: governor, $2: loop
> +parse_tbench()
> +{
> + awk '{print $5}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-des-perf-$1-$2.log
> + avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-des-perf-$1-$2.log)
> + printf "Tbench-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result
> +
> + awk '{print $7}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-freq-$1-$2.log
> + avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-freq-$1-$2.log)
> + printf "Tbench-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result
> +
> + awk '{print $11}' results/tracer-tbench-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_TBENCH-load-$1-$2.log
> + avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_TBENCH-load-$1-$2.log)
> + printf "Tbench-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result
> +
> + grep Throughput $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $2}' > $OUTFILE_TBENCH-throughput-$1-$2.log
> + tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1-$2.log)
> + printf "Tbench-$1-#$2 throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result
> +
> + grep Joules $OUTFILE_TBENCH-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_TBENCH-energy-$1-$2.log
> + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1-$2.log)
> + printf "Tbench-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result
> +
> + ppw=`echo "scale=4;($TIME_LIMIT-1)*$tp_sum/$en_sum" | bc | awk '{printf "%.4f", $0}'`
> + printf "Tbench-$1-#$2 PPW(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result
> + printf "\n" | tee -a $OUTFILE_TBENCH.result
Please clarify PPW = performance per watt here.
> +
> + store_csv_tbench $1 $2 $avg_des_perf $avg_freq $avg_load $tp_sum $en_sum $ppw
> +}
> +
> +# $1: governor
> +loop_tbench()
> +{
> + printf "\nTbench total test times is $LOOP_TIMES for $1\n\n"
> + for i in `seq 1 $LOOP_TIMES`
> + do
> + run_tbench $1 $i
> + parse_tbench $1 $i
> + done
> +}
> +
> +# $1: governor
> +gather_tbench()
> +{
> + printf "Tbench test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_TBENCH.result
> + printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_TBENCH.result
> +
> + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_TBENCH-des-perf-$1.log
> + avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-des-perf-$1.log)
> + printf "Tbench-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_TBENCH.result
> +
> + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_TBENCH-freq-$1.log
> + avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-freq-$1.log)
> + printf "Tbench-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_TBENCH.result
> +
> + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_TBENCH-load-$1.log
> + avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-load-$1.log)
> + printf "Tbench-$1 avg load: $avg_load\n" | tee -a $OUTFILE_TBENCH.result
> +
> + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "throughput(MB/s):" | awk '{print $NF}' > $OUTFILE_TBENCH-throughput-$1.log
> + tp_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-throughput-$1.log)
> + printf "Tbench-$1 total throughput(MB/s): $tp_sum\n" | tee -a $OUTFILE_TBENCH.result
> +
> + avg_tp=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-throughput-$1.log)
> + printf "Tbench-$1 avg throughput(MB/s): $avg_tp\n" | tee -a $OUTFILE_TBENCH.result
> +
> + grep "Tbench-$1-#" $OUTFILE_TBENCH.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_TBENCH-energy-$1.log
> + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_TBENCH-energy-$1.log)
> + printf "Tbench-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_TBENCH.result
> +
> + avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_TBENCH-energy-$1.log)
> + printf "Tbench-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_TBENCH.result
> +
> + ppw=`echo "scale=4;($TIME_LIMIT-1)*$avg_tp/$avg_en" | bc | awk '{printf "%.4f", $0}'`
> + printf "Tbench-$1 PPW(MB/J): $ppw\n" | tee -a $OUTFILE_TBENCH.result
> + printf "\n" | tee -a $OUTFILE_TBENCH.result
It's better to add commment here to describe the formula that how to caculate the performance per watt (PPW) result for the tbench tests.
> +
> + store_csv_tbench $1 "Average" $avg_des_perf $avg_freq $avg_load $avg_tp $avg_en $ppw
> + empty_line_csv_tbench
> +}
> +
> +amd_pstate_tbench()
> +{
> + printf "\n---------------------------------------------\n"
> + printf "*** Running AMD P-state tbench ***"
> + printf "\n---------------------------------------------\n"
> +
> + pre_clear_tbench
> +
> + install_tbench
> +
> + store_csv_tbench "Governor" "Round" "Des-perf" "Freq" "Load" "Performance(MB/s)" "Energy(Joules)" "PPW(MB/J)"
The same comment here above, we would better to have abbreviation
desciption for PPW in the result.
Thanks,
Ray
> +
> + for_each_policy backup_governor
> +
> + for governor in ${tbench_governors[*]} ; do
> + printf "\nSpecified governor is $governor\n\n"
> + for_each_policy switch_governor $governor
> + loop_tbench $governor
> + gather_tbench $governor
> + done
> +
> + restore_governor
> +
> + post_clear_tbench
> +}
> --
> 2.25.1
>
On Wed, Jul 06, 2022 at 03:36:21PM +0800, Meng, Li (Jassmine) wrote:
> Add gitsource.sh trigger the gitsource testing and monitor the cpu desire
> performance, frequency, load, power consumption and throughput etc.
>
> Signed-off-by: Meng Li <[email protected]>
> ---
> tools/testing/selftests/amd-pstate/Makefile | 2 +-
> .../testing/selftests/amd-pstate/gitsource.sh | 176 ++++++++++++++++++
> tools/testing/selftests/amd-pstate/main.sh | 21 ++-
> 3 files changed, 195 insertions(+), 4 deletions(-)
> create mode 100755 tools/testing/selftests/amd-pstate/gitsource.sh
>
> diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
> index e2fb03381a32..c536b9303858 100644
> --- a/tools/testing/selftests/amd-pstate/Makefile
> +++ b/tools/testing/selftests/amd-pstate/Makefile
> @@ -13,6 +13,6 @@ TEST_GEN_FILES += ../../../power/x86/intel_pstate_tracer/intel_pstate_tracer.py
> endif
>
> TEST_PROGS := run.sh
> -TEST_FILES := main.sh basic.sh tbench.sh
> +TEST_FILES := main.sh basic.sh tbench.sh gitsource.sh
>
> include ../lib.mk
> diff --git a/tools/testing/selftests/amd-pstate/gitsource.sh b/tools/testing/selftests/amd-pstate/gitsource.sh
> new file mode 100755
> index 000000000000..0631a4839f5d
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/gitsource.sh
> @@ -0,0 +1,176 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# Testing and monitor the cpu frequency and performance when
> +# this script trigger gitsource test.
> +
> +# protect against multiple inclusion
> +if [ $FILE_GITSOURCE ]; then
> + return 0
> +else
> + FILE_GITSOURCE=DONE
> +fi
> +
> +git_name="git-2.15.1"
> +git_tar="$git_name.tar.gz"
> +gitsource_url="https://github.com/git/git/archive/refs/tags/v2.15.1.tar.gz"
> +gitsource_governors=("ondemand" "schedutil")
> +
> +# $1: governor, $2: round, $3: des-perf, $4: freq, $5: load, $6: time $7: energy, $8: PPW
> +store_csv_gitsource()
> +{
> + echo "$1, $2, $3, $4, $5, $6, $7, $8" | tee -a $OUTFILE_GIT.csv > /dev/null 2>&1
> +}
> +
> +empty_line_csv_gitsource()
> +{
> + echo "" | tee -a $OUTFILE_GIT.csv > /dev/null 2>&1
> +}
> +
> +pre_clear_gitsource()
> +{
> + rm -rf results/tracer-gitsource*
> +}
> +
> +post_clear_gitsource()
> +{
> + rm -rf results/tracer-gitsource*
> + rm -rf $OUTFILE_GIT*.log
> +}
> +
> +install_gitsource()
> +{
> + if [ ! -d $git_name ]; then
> + printf "Download gitsource, please wait a moment ...\n\n"
> + wget -O $git_tar $gitsource_url > /dev/null 2>&1
> +
> + printf "Tar gitsource ...\n\n"
> + tar -xzf $git_tar
> + fi
> +}
> +
> +# $1: governor, $2: loop
> +run_gitsource()
> +{
> + echo "Launching amd pstate tracer for $1 #$2 tracer_interval: $TRACER_INTERVAL"
> + ./amd_pstate_trace.py -n tracer-gitsource-$1-$2 -i $TRACER_INTERVAL > /dev/null 2>&1
> +
> + printf "Make and test gitsource for $1 #$2 make_cpus: $MAKE_CPUS\n"
> + cd $git_name
> + ./../perf stat -a --per-socket -I 1000 -e power/energy-pkg/ /usr/bin/time -o ../$OUTFILE_GIT.time-gitsource-$1-$2.log make test -j$MAKE_CPUS > ../$OUTFILE_GIT-perf-$1-$2.log 2>&1
> + cd ..
> +
> + for job in `jobs -p`
> + do
> + echo "Waiting for job id $job"
> + wait $job
> + done
> +}
> +
> +# $1: governor, $2: loop
> +parse_gitsource()
> +{
> + awk '{print $5}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-des-perf-$1-$2.log
> + avg_des_perf=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-des-perf-$1-$2.log)
> + printf "Gitsource-$1-#$2 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result
> +
> + awk '{print $7}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-freq-$1-$2.log
> + avg_freq=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-freq-$1-$2.log)
> + printf "Gitsource-$1-#$2 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result
> +
> + awk '{print $11}' results/tracer-gitsource-$1-$2/cpu.csv | sed -e '1d' | sed s/,// > $OUTFILE_GIT-load-$1-$2.log
> + avg_load=$(awk 'BEGIN {i=0; sum=0};{i++; sum += $1};END {print sum/i}' $OUTFILE_GIT-load-$1-$2.log)
> + printf "Gitsource-$1-#$2 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result
> +
> + grep user $OUTFILE_GIT.time-gitsource-$1-$2.log | awk '{print $1}' | sed -e 's/user//' > $OUTFILE_GIT-time-$1-$2.log
> + time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1-$2.log)
> + printf "Gitsource-$1-#$2 user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result
> +
> + grep Joules $OUTFILE_GIT-perf-$1-$2.log | awk '{print $4}' > $OUTFILE_GIT-energy-$1-$2.log
> + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1-$2.log)
> + printf "Gitsource-$1-#$2 power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
> +
> + ppw=`echo "scale=4;$time_sum/$en_sum" | bc | awk '{printf "%.4f", $0}'`
> + printf "Gitsource-$1-#$2 PPW(s/J): $ppw\n" | tee -a $OUTFILE_GIT.result
> + printf "\n" | tee -a $OUTFILE_GIT.result
> +
> + store_csv_gitsource $1 $2 $avg_des_perf $avg_freq $avg_load $time_sum $en_sum $ppw
> +}
> +
> +# $1: governor:w
> +
> +loop_gitsource()
> +{
> + printf "\nGitsource total test times is $LOOP_TIMES for $1\n\n"
> + for i in `seq 1 $LOOP_TIMES`
> + do
> + run_gitsource $1 $i
> + parse_gitsource $1 $i
> + done
> +}
> +
> +# $1: governor
> +gather_gitsource()
> +{
> + printf "Gitsource test result for $1 (loops:$LOOP_TIMES)" | tee -a $OUTFILE_GIT.result
> + printf "\n--------------------------------------------------\n" | tee -a $OUTFILE_GIT.result
> +
> + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg des perf:" | awk '{print $NF}' > $OUTFILE_GIT-des-perf-$1.log
> + avg_des_perf=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-des-perf-$1.log)
> + printf "Gitsource-$1 avg des perf: $avg_des_perf\n" | tee -a $OUTFILE_GIT.result
> +
> + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg freq:" | awk '{print $NF}' > $OUTFILE_GIT-freq-$1.log
> + avg_freq=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-freq-$1.log)
> + printf "Gitsource-$1 avg freq: $avg_freq\n" | tee -a $OUTFILE_GIT.result
> +
> + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "avg load:" | awk '{print $NF}' > $OUTFILE_GIT-load-$1.log
> + avg_load=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-load-$1.log)
> + printf "Gitsource-$1 avg load: $avg_load\n" | tee -a $OUTFILE_GIT.result
> +
> + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "user time(s):" | awk '{print $NF}' > $OUTFILE_GIT-time-$1.log
> + time_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-time-$1.log)
> + printf "Gitsource-$1 total user time(s): $time_sum\n" | tee -a $OUTFILE_GIT.result
> +
> + avg_time=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-time-$1.log)
> + printf "Gitsource-$1 avg user times(s): $avg_time\n" | tee -a $OUTFILE_GIT.result
> +
> + grep "Gitsource-$1-#" $OUTFILE_GIT.result | grep "power consumption(J):" | awk '{print $NF}' > $OUTFILE_GIT-energy-$1.log
> + en_sum=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum}' $OUTFILE_GIT-energy-$1.log)
> + printf "Gitsource-$1 total power consumption(J): $en_sum\n" | tee -a $OUTFILE_GIT.result
> +
> + avg_en=$(awk 'BEGIN {sum=0};{sum += $1};END {print sum/'$LOOP_TIMES'}' $OUTFILE_GIT-energy-$1.log)
> + printf "Gitsource-$1 avg power consumption(J): $avg_en\n" | tee -a $OUTFILE_GIT.result
> +
> + ppw=`echo "scale=4;$avg_time/$avg_en" | bc | awk '{printf "%.4f", $0}'`
> + printf "Gitsource-$1 PPW(s/J): $ppw\n" | tee -a $OUTFILE_GIT.result
> + printf "\n" | tee -a $OUTFILE_GIT.result
The same commment that last patch, we would better have a decription for
formula to caculate the performance per watt data here.
> +
> + store_csv_gitsource $1 "Average" $avg_des_perf $avg_freq $avg_load $avg_time $avg_en $ppw
> + empty_line_csv_gitsource
> +}
> +
> +amd_pstate_gitsource()
> +{
> + printf "\n---------------------------------------------\n"
> + printf "*** Running AMD P-state gitsource ***"
> + printf "\n---------------------------------------------\n"
> +
> + pre_clear_gitsource
> +
> + install_gitsource
> +
> + store_csv_gitsource "Governor" "Round" "Des-perf" "Freq" "Load" "Time(s)" "Energy(Joules)" "PPW(s/J)"
Clarify the full name of PPW.
> +
> + for_each_policy backup_governor
> +
> + for governor in ${gitsource_governors[*]} ; do
> + printf "\nSpecified governor is $governor\n\n"
> + for_each_policy switch_governor $governor
> + loop_gitsource $governor
> + gather_gitsource $governor
> + done
> +
> + restore_governor
> +
> + post_clear_gitsource
> +}
> diff --git a/tools/testing/selftests/amd-pstate/main.sh b/tools/testing/selftests/amd-pstate/main.sh
> index ae71fe62e3b0..69bf8ea371a5 100755
> --- a/tools/testing/selftests/amd-pstate/main.sh
> +++ b/tools/testing/selftests/amd-pstate/main.sh
> @@ -10,6 +10,7 @@ fi
>
> source basic.sh
> source tbench.sh
> +source 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/')
> @@ -18,6 +19,7 @@ VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}')
> FUNC=all
> OUTFILE=selftest
> OUTFILE_TBENCH="$OUTFILE.tbench"
> +OUTFILE_GIT="$OUTFILE.gitsource"
>
> SYSFS=
> CPUROOT=
> @@ -126,6 +128,9 @@ amd_pstate_all()
>
> # tbench
> amd_pstate_tbench
> +
> + # gitsource
> + amd_pstate_gitsource
> }
>
> helpme()
> @@ -135,7 +140,8 @@ helpme()
> [-o <output-file-for-dump>]
> [-c <all: All testing,
> basic: Basic testing,
> - tbench: Tbench testing.>]
> + tbench: Tbench testing,
> + gitsource: Gitsource testing.>]
> [-t <tbench time limit>]
> [-p <tbench process number>]
> [-l <loop times for tbench]
Can we add an option to draw the chart of each times of performance and
energy/power data? It's absolutely better than raw table.
Thanks,
Ray
> @@ -153,7 +159,7 @@ parse_arguments()
> helpme
> ;;
>
> - c) # --func_type (Function to perform: basic, tbench (default: all))
> + c) # --func_type (Function to perform: basic, tbench, gitsource (default: all))
> FUNC=$OPTARG
> ;;
>
> @@ -169,7 +175,7 @@ parse_arguments()
> PROCESS_NUM=$OPTARG
> ;;
>
> - l) # --tbench-loop-times
> + l) # --tbench/gitsource-loop-times
> LOOP_TIMES=$OPTARG
> ;;
>
> @@ -259,6 +265,10 @@ do_test()
> amd_pstate_tbench
> ;;
>
> + "gitsource")
> + amd_pstate_gitsource
> + ;;
> +
> *)
> echo "Invalid [-f] function type"
> helpme
> @@ -283,6 +293,11 @@ pre_clear_dumps()
> rm -rf $OUTFILE_TBENCH*
> ;;
>
> + "gitsource")
> + rm -rf $OUTFILE.log
> + rm -rf $OUTFILE.backup_governor.log
> + rm -rf $OUTFILE_GIT*
> + ;;
> esac
> }
>
> --
> 2.25.1
>
On 7/6/22 02:36, Meng Li wrote:
> Modify amd-pstate-ut.sh to basic.sh.
> The purpose of this modification is to facilitate the subsequent
> addition of gitsource, tbench and other tests.
>
> Signed-off-by: Meng Li <[email protected]>
> ---
> tools/testing/selftests/amd-pstate/Makefile | 3 +-
> .../selftests/amd-pstate/amd-pstate-ut.sh | 55 --------
> tools/testing/selftests/amd-pstate/basic.sh | 38 +++++
> tools/testing/selftests/amd-pstate/main.sh | 131 ++++++++++++++++++
> tools/testing/selftests/amd-pstate/run.sh | 15 ++
> 5 files changed, 186 insertions(+), 56 deletions(-)
> delete mode 100755 tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> create mode 100755 tools/testing/selftests/amd-pstate/basic.sh
> create mode 100755 tools/testing/selftests/amd-pstate/main.sh
> create mode 100755 tools/testing/selftests/amd-pstate/run.sh
>
> diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
> index 199867f44b32..167ab51ec290 100644
> --- a/tools/testing/selftests/amd-pstate/Makefile
> +++ b/tools/testing/selftests/amd-pstate/Makefile
> @@ -4,6 +4,7 @@
> # No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
> all:
>
> -TEST_PROGS := amd-pstate-ut.sh
> +TEST_PROGS := run.sh
> +TEST_FILES := main.sh basic.sh
>
> include ../lib.mk
> diff --git a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh b/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> deleted file mode 100755
> index 273364650285..000000000000
> --- a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -#!/bin/sh
> -# SPDX-License-Identifier: GPL-2.0
> -
> -# amd-pstate-ut is a test module for testing the amd-pstate driver.
> -# It can only run on x86 architectures and current cpufreq driver
> -# must be amd-pstate.
> -# (1) It can help all users to verify their processor support
> -# (SBIOS/Firmware or Hardware).
> -# (2) Kernel can have a basic function test to avoid the kernel
> -# regression during the update.
> -# (3) We can introduce more functional or performance tests to align
> -# the result together, it will benefit power and performance scale optimization.
> -
> -# Kselftest framework requirement - SKIP code is 4.
> -ksft_skip=4
> -
> -# 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}')
> -
> -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 [ "$scaling_driver" != "amd-pstate" ]; then
> - echo "$0 # Skipped: Test can only run on amd-pstate driver."
> - echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
> - exit $ksft_skip
> -fi
> -
> -msg="Skip all tests:"
> -if [ ! -w /dev ]; then
> - echo $msg please run this as root >&2
> - exit $ksft_skip
> -fi
> -
> -if ! /sbin/modprobe -q -n amd-pstate-ut; then
> - echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]"
> - exit $ksft_skip
> -fi
> -if /sbin/modprobe -q amd-pstate-ut; then
> - /sbin/modprobe -q -r amd-pstate-ut
> - echo "amd-pstate-ut: ok"
> -else
> - echo "amd-pstate-ut: [FAIL]"
> - exit 1
> -fi
> diff --git a/tools/testing/selftests/amd-pstate/basic.sh b/tools/testing/selftests/amd-pstate/basic.sh
> new file mode 100755
> index 000000000000..e4c43193e4a3
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/basic.sh
> @@ -0,0 +1,38 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# amd-pstate-ut is a test module for testing the amd-pstate driver.
> +# It can only run on x86 architectures and current cpufreq driver
> +# must be amd-pstate.
> +# (1) It can help all users to verify their processor support
> +# (SBIOS/Firmware or Hardware).
> +# (2) Kernel can have a basic function test to avoid the kernel
> +# regression during the update.
> +# (3) We can introduce more functional or performance tests to align
> +# the result together, it will benefit power and performance scale optimization.
> +
> +# protect against multiple inclusion
> +if [ $FILE_BASIC ]; then
> + return 0
> +else
> + FILE_BASIC=DONE
> +fi
> +
> +amd_pstate_basic()
> +{
> + printf "\n---------------------------------------------\n"
> + printf "*** Running AMD P-state ut ***"
> + printf "\n---------------------------------------------\n"
> +
> + if ! /sbin/modprobe -q -n amd-pstate-ut; then
> + echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]"
> + exit $ksft_skip
> + fi
> + if /sbin/modprobe -q amd-pstate-ut; then
> + /sbin/modprobe -q -r amd-pstate-ut
> + echo "amd-pstate-basic: ok"
> + else
> + echo "amd-pstate-basic: [FAIL]"
> + exit 1
> + fi
> +}
> diff --git a/tools/testing/selftests/amd-pstate/main.sh b/tools/testing/selftests/amd-pstate/main.sh
> new file mode 100755
> index 000000000000..1c28b5d7b4c5
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/main.sh
> @@ -0,0 +1,131 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# protect against multiple inclusion
> +if [ $FILE_MAIN ]; then
> + return 0
> +else
> + FILE_MAIN=DONE
> +fi
> +
> +source basic.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}')
> +
> +FUNC=all
> +OUTFILE=selftest
> +
> +# Kselftest framework requirement - SKIP code is 4.
> +ksft_skip=4
> +
> +# All amd-pstate tests
> +amd_pstate_all()
> +{
> + printf "\n=============================================\n"
> + printf "***** Running AMD P-state Sanity Tests *****\n"
> + printf "=============================================\n\n"
> +
> + # unit test for amd-pstate kernel driver
> + amd_pstate_basic
> +}
> +
> +helpme()
> +{
> + printf "Usage: $0 [OPTION...]
> + [-h <help>]
> + [-o <output-file-for-dump>]
> + [-c <all: All testing,
> + basic: Basic testing.>]
> + \n"
> + exit 2
> +}
> +
> +parse_arguments()
> +{
> + while getopts ho:c: arg
> + do
> + case $arg in
> + h) # --help
> + helpme
> + ;;
> +
> + c) # --func_type (Function to perform: basic (default: all))
> + FUNC=$OPTARG
> + ;;
> +
> + o) # --output-file (Output file to store dumps)
> + OUTFILE=$OPTARG
> + ;;
> +
> + \?)
> + helpme
> + ;;
> + esac
> + done
> +}
> +
> +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 [ "$scaling_driver" != "amd-pstate" ]; then
> + echo "$0 # Skipped: Test can only run on amd-pstate driver."
> + echo "$0 # Current cpufreq scaling drvier is $scaling_driver."
> + exit $ksft_skip
> + fi
> +
> + msg="Skip all tests:"
> + if [ ! -w /dev ]; then
> + echo $msg please run this as root >&2
> + exit $ksft_skip
> + fi
> +}
> +
> +do_test()
> +{
> + case "$FUNC" in
> + "all")
> + amd_pstate_all
> + ;;
> +
> + "basic")
> + amd_pstate_basic
> + ;;
> +
> + *)
> + echo "Invalid [-f] function type"
> + helpme
> + ;;
> + esac
> +}
> +
> +# clear dumps
> +pre_clear_dumps()
> +{
> + case "$FUNC" in
> + "all")
> + rm -rf $OUTFILE*
> + ;;
> +
> + "basic")
> + ;;
> +
> + esac
Small nit. You have two different indentation styles for your case statements, do_test
and pre_clear_dumps vs parse_arguments. Would be nice to stick to a single style.
> +}
> +
> +post_clear_dumps()
> +{
> + rm -rf $OUTFILE.log
> +}
> diff --git a/tools/testing/selftests/amd-pstate/run.sh b/tools/testing/selftests/amd-pstate/run.sh
> new file mode 100755
> index 000000000000..247e80bfee44
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/run.sh
> @@ -0,0 +1,15 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +source main.sh
> +
> +# 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
run.sh seems like it's just a wrapper for main.sh, can these two files be merged into a single file?
-Nathan