Hi all:
AMD P-State unit test(amd-pstate-ut) is a kernel module for testing
the functions of amd-pstate driver.
It could import as a module to launch some test tasks.
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
together, it will benefit power and performance scale optimization.
We upstream out AMD P-state driver into Linux kernel and use this unit
test module to verify the required conditions and basic functions of
amd-pstate before integration test.
We use test module in the kselftest frameworks to implement it.
We create amd-pstate-ut module and tie it into kselftest.
For example: The test case aput_acpi_cpc is used to check whether the
_CPC object is exist in SBIOS.
The amd-pstate initialization will fail if the _CPC in ACPI SBIOS is not
existed at the detected processor, so it is a necessary condition.
At present, it only implements the basic framework and some simple test
cases.
TODO : 1) we will add more test cases to improve the depth and coverage of
the test. E.X. use the script to trigger the tbench, gitsource, kernbench,
netperf, speedometer, and etc. testing and monitor the cpu frequency and
performance goals change, power consumption at runtime.
Please check the documentation amd-pstate.rst for details of the test steps.
See patch series in below git repo:
V1: https://lore.kernel.org/linux-pm/[email protected]/
V2: https://lore.kernel.org/lkml/[email protected]/
V3: https://lore.kernel.org/lkml/[email protected]/
V4: https://lore.kernel.org/lkml/[email protected]/
Changes from V1 -> V2:
- cpufreq: amd-pstate:
- - add a trailing of amd-pstate.h to MAINTAINER AMD PSTATE DRIVER.
- selftests: cpufreq:
- - add a wrapper shell script for the amd_pstate_testmod module.
- selftests: cpufreq:
- - remove amd_pstate_testmod kernel module to
.../cpufreq/amd_pstate_testmod.
- Documentation: amd-pstate:
- - amd_pstate_testmod rst document is not provided at present.
Changes from V2 -> V3:
- cpufreq: amd-pstate:
- - adjust the order of add amd-pstate.h in MAINTAINERS.
- selftests: cpufreq:
- - remove the call of amd_pstate_testmod.sh from cpufreq Makefile to
main.sh.
- selftests: cpufreq:
- - add explain the goal or intention of the AMD P-State Unit Test
module.
- - modify comments.
- - use the checkpatch.pl to check my patches.
- - add conditions judgment before formal test.
- - delete some unnecessary test cases.
- - modify test cases about perf and performance etc.
Changes from V3 -> V4:
- selftests: amd-pstate:
- - remove script and test module to tools/testing/selftests/amd-pstate/
- - uniformly named amd-pstate-ut.
- - check current architectures and cpufreq driver in amd-pstate-ut.sh
- - delete codes about conditions in amd-pstate-ut.c
- Documentation: amd-pstate:
- - add introduce document about amd-pstate unit test.
Changes from V4 -> V5:
- selftests: amd-pstate:
- - add print the current scaling_driver.
- - add amd-pstate-ut.ko into TEST_GEN_FILES.
- - move "insmod/rmmod amd-pstate-ut.ko" stuff into script amd_pstate_ut.sh
- - add a check of read back from X86_FEATURE_CPPC in get_shared_mem().
- Documentation: amd-pstate:
- - delete the test step about insmod/rmmod amd-pstate-ut.ko
Changes from V5 -> V6:
- cpufreq: amd-pstate:
- - add amd-pstate-ut test codes to drivers/cpurfreq
- - add the macro CONFIG_X86_AMD_PSTATE_UT
- selftests: amd-pstate:
- - delete amd-pstate-ut test codes from tools/testing/selftests/amd-pstate/
Thanks,
Jasmine
Meng Li (4):
cpufreq: amd-pstate: Expose struct amd_cpudata
cpufreq: amd-pstate: Add test module for amd-pstate driver
selftests: amd-pstate: Add test trigger for amd-pstate driver
Documentation: amd-pstate: Add unit test introduction
Documentation/admin-guide/pm/amd-pstate.rst | 84 ++++++
MAINTAINERS | 1 +
drivers/cpufreq/Kconfig.x86 | 6 +
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/amd-pstate-ut.c | 278 ++++++++++++++++++
drivers/cpufreq/amd-pstate.c | 60 +---
include/linux/amd-pstate.h | 77 +++++
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/amd-pstate/Makefile | 8 +
.../selftests/amd-pstate/amd-pstate-ut.sh | 34 +++
tools/testing/selftests/amd-pstate/config | 1 +
11 files changed, 492 insertions(+), 59 deletions(-)
create mode 100644 drivers/cpufreq/amd-pstate-ut.c
create mode 100644 include/linux/amd-pstate.h
create mode 100644 tools/testing/selftests/amd-pstate/Makefile
create mode 100755 tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
create mode 100644 tools/testing/selftests/amd-pstate/config
--
2.25.1
Introduce the AMD P-State unit test module design and implementation.
Signed-off-by: Meng Li <[email protected]>
Acked-by: Huang Rui <[email protected]>
---
Documentation/admin-guide/pm/amd-pstate.rst | 84 +++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index 83b58eb4ab4d..222e4f5fd817 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -182,6 +182,7 @@ to the ``struct sugov_cpu`` that the utilization update belongs to.
Then, ``amd-pstate`` updates the desired performance according to the CPU
scheduler assigned.
+.. _processor_support:
Processor Support
=======================
@@ -282,6 +283,8 @@ efficiency frequency management method on AMD processors.
Kernel Module Options for ``amd-pstate``
=========================================
+.. _shared_mem:
+
``shared_mem``
Use a module param (shared_mem) to enable related processors manually with
**amd_pstate.shared_mem=1**.
@@ -393,6 +396,84 @@ about part of the output. ::
CPU_005 712 116384 39 49 166 0.7565 9645075 2214891 38431470 25.1 11.646 469 2.496 kworker/5:0-40
CPU_006 712 116408 39 49 166 0.6769 8950227 1839034 37192089 24.06 11.272 470 2.496 kworker/6:0-1264
+Unit Tests for amd-pstate
+-------------------------
+
+``amd-pstate-ut`` is a test module for testing the ``amd-pstate`` driver.
+
+ * It can help all users to verify their processor support (SBIOS/Firmware or Hardware).
+
+ * Kernel can have a basic function test to avoid the kernel regression during the update.
+
+ * We can introduce more functional or performance tests to align the result together, it will benefit power and performance scale optimization.
+
+1. Test case decriptions
+
+ +---------+--------------------------------+------------------------------------------------------------------------------------+
+ | Index | Functions | Description |
+ +=========+================================+====================================================================================+
+ | 0 | aput_acpi_cpc || Check whether the _CPC object is present in SBIOS. |
+ | | || |
+ | | || The detail refer to `Processor Support <processor_support_>`_. |
+ +---------+--------------------------------+------------------------------------------------------------------------------------+
+ | 1 | aput_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 | aput_check_perf || Check if the each performance values are reasonable. |
+ | | || highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0. |
+ +---------+--------------------------------+------------------------------------------------------------------------------------+
+ | 3 | aput_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``. |
+ +---------+--------------------------------+------------------------------------------------------------------------------------+
+
+#. 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
+
+ + open the :c:macro:`CONFIG_X86_AMD_PSTATE` configuration option.
+ + set the :c:macro:`CONFIG_X86_AMD_PSTATE_UT` configuration option to M.
+ + make project
+ + make selftest ::
+
+ jasminemeng@jasmine-meng:~/amd-brahma$ cd linux
+ jasminemeng@jasmine-meng:~/amd-brahma/linux$ make -C tools/testing/selftests
+
+ #. Installation & Steps ::
+
+ jasmine@jasmine-meng:~/amd-brahma/linux$ make -C tools/testing/selftests install INSTALL_PATH=~/kselftest
+ jasmine@jasmine-meng:~$ 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 ::
+
+ jasmine@jasmine-meng:~$ dmesg | grep "amd-pstate-ut" | tee log.txt
+ [76697.480217] amd-pstate-ut: loaded.
+ [76697.480222] amd-pstate-ut: ****** Begin 1 acpi_cpc_valid ******
+ [76697.480227] amd-pstate-ut: ****** End 1 acpi_cpc_valid ******
+ [76697.480228] amd-pstate-ut: ****** Begin 2 check_enabled ******
+ [76697.480253] amd-pstate-ut: ****** End 2 check_enabled ******
+ [76697.480255] amd-pstate-ut: ****** Begin 3 check_perf ******
+ [76697.480554] amd-pstate-ut: ****** End 3 check_perf ******
+ [76697.480556] amd-pstate-ut: ****** Begin 4 check_freq ******
+ [76697.480558] amd-pstate-ut: ****** End 4 check_freq ******
+ [76697.480559] amd-pstate-ut: all 4 tests passed
+ [76697.482507] amd-pstate-ut: unloaded.
+
Reference
===========
@@ -405,3 +486,6 @@ Reference
.. [3] Processor Programming Reference (PPR) for AMD Family 19h Model 51h, Revision A1 Processors
https://www.amd.com/system/files/TechDocs/56569-A1-PUB.zip
+
+.. [4] Linux Kernel Selftests,
+ https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html
--
2.25.1
Add amd-pstate test trigger in kselftest, it will load/unload
amd-pstate-ut module to test some cases etc.
Signed-off-by: Meng Li <[email protected]>
Acked-by: Huang Rui <[email protected]>
---
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/amd-pstate/Makefile | 8 +++++
.../selftests/amd-pstate/amd-pstate-ut.sh | 34 +++++++++++++++++++
tools/testing/selftests/amd-pstate/config | 1 +
4 files changed, 44 insertions(+)
create mode 100644 tools/testing/selftests/amd-pstate/Makefile
create mode 100755 tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
create mode 100644 tools/testing/selftests/amd-pstate/config
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 2319ec87f53d..975c13368286 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
TARGETS += alsa
+TARGETS += amd-pstate
TARGETS += arm64
TARGETS += bpf
TARGETS += breakpoints
diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
new file mode 100644
index 000000000000..e1432112fb70
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Makefile for amd-pstate/ function selftests
+
+TEST_PROGS := amd-pstate-ut.sh
+
+include ../lib.mk
+
+$(TEST_GEN_FILES): $(HEADERS)
diff --git a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh b/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
new file mode 100755
index 000000000000..970f7a76c7d5
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+# amd-pstate-ut is a test module for testing the amd-pstate driver.
+# (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
+
+if ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then
+ echo "$0 # Skipped: Test can only run on x86 architectures."
+ exit $ksft_skip
+fi
+
+msg="Skip all tests:"
+if [ ! -w /dev ]; then
+ echo $msg please run this as root >&2
+ 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
+
+$(dirname $0)/../kselftest/module.sh "amd-pstate-ut" amd-pstate-ut
diff --git a/tools/testing/selftests/amd-pstate/config b/tools/testing/selftests/amd-pstate/config
new file mode 100644
index 000000000000..f43103c9adc4
--- /dev/null
+++ b/tools/testing/selftests/amd-pstate/config
@@ -0,0 +1 @@
+CONFIG_X86_AMD_PSTATE_UT=m
--
2.25.1
Add amd-pstate-ut module, which is conceptually out-of-tree module
and provides ways for selftests/amd-pstate driver to test various
kernel module-related functionality. This module will be expected by
some of selftests to be present and loaded.
Signed-off-by: Meng Li <[email protected]>
Acked-by: Huang Rui <[email protected]>
---
drivers/cpufreq/Kconfig.x86 | 6 +
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/amd-pstate-ut.c | 278 ++++++++++++++++++++++++++++++++
3 files changed, 285 insertions(+)
create mode 100644 drivers/cpufreq/amd-pstate-ut.c
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index 55516043b656..37ba282cd156 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -51,6 +51,12 @@ config X86_AMD_PSTATE
If in doubt, say N.
+config X86_AMD_PSTATE_UT
+ tristate "selftest for AMD Processor P-State driver"
+ depends on X86_AMD_PSTATE
+ help
+ This kernel module is used for testing. It's safe to say M here.
+
config X86_ACPI_CPUFREQ
tristate "ACPI Processor P-States driver"
depends on ACPI_PROCESSOR
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 285de70af877..49b98c62c5af 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -30,6 +30,7 @@ amd_pstate-y := amd-pstate.o amd-pstate-trace.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o
+obj-$(CONFIG_X86_AMD_PSTATE_UT) += amd-pstate-ut.o
obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
new file mode 100644
index 000000000000..a510355b804e
--- /dev/null
+++ b/drivers/cpufreq/amd-pstate-ut.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-1.0-or-later
+/*
+ * AMD Processor P-state Frequency Driver Unit Test
+ *
+ * Copyright (C) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ * Author: Meng Li <[email protected]>
+ *
+ * The AMD P-State Unit Test is a test module for testing the amd-pstate
+ * driver. 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.
+ *
+ * At present, it only implements the basic framework and some simple
+ * test cases. Next, 1) we will add a rst document. 2) we will add more
+ * test cases to improve the depth and coverage of the test.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "../tools/testing/selftests/kselftest_module.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/fs.h>
+#include <linux/amd-pstate.h>
+
+#include <acpi/cppc_acpi.h>
+
+/*
+ * Abbreviations:
+ * aput: used as a shortform for AMD P-State unit test.
+ * It helps to keep variable names smaller, simpler
+ */
+
+KSTM_MODULE_GLOBALS();
+
+/*
+ * Kernel module for testing the AMD P-State unit test
+ */
+enum aput_result {
+ APUT_RESULT_PASS,
+ APUT_RESULT_FAIL,
+ MAX_APUT_RESULT,
+};
+
+struct aput_struct {
+ const char *name;
+ void (*func)(u32 index);
+ enum aput_result result;
+};
+
+static void aput_acpi_cpc(u32 index);
+static void aput_check_enabled(u32 index);
+static void aput_check_perf(u32 index);
+static void aput_check_freq(u32 index);
+
+static struct aput_struct aput_cases[] = {
+ {"acpi_cpc_valid", aput_acpi_cpc },
+ {"check_enabled", aput_check_enabled },
+ {"check_perf", aput_check_perf },
+ {"check_freq", aput_check_freq }
+};
+
+static bool get_shared_mem(void)
+{
+ bool result = false;
+ char buf[5] = {0};
+ struct file *filp = NULL;
+ loff_t pos = 0;
+ ssize_t ret;
+
+ if (!boot_cpu_has(X86_FEATURE_CPPC)) {
+ filp = filp_open("/sys/module/amd_pstate/parameters/shared_mem", FMODE_PREAD, 0);
+ if (IS_ERR(filp))
+ pr_err("%s Open param file fail!\n", __func__);
+ else {
+ ret = kernel_read(filp, &buf, sizeof(buf), &pos);
+ if (ret < 0)
+ pr_err("%s ret=%ld unable to read from param file!\n",
+ __func__, ret);
+ filp_close(filp, NULL);
+ }
+
+ if ('Y' == *buf)
+ result = true;
+ }
+
+ return result;
+}
+
+static void aput_acpi_cpc(u32 index)
+{
+ if (acpi_cpc_valid())
+ aput_cases[index].result = APUT_RESULT_PASS;
+ else
+ aput_cases[index].result = APUT_RESULT_FAIL;
+}
+
+static void aput_pstate_enable(u32 index)
+{
+ int ret = 0;
+ u64 cppc_enable = 0;
+
+ ret = rdmsrl_safe(MSR_AMD_CPPC_ENABLE, &cppc_enable);
+ if (ret) {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s rdmsrl_safe MSR_AMD_CPPC_ENABLE ret=%d is error!\n", __func__, ret);
+ return;
+ }
+ if (cppc_enable)
+ aput_cases[index].result = APUT_RESULT_PASS;
+ else
+ aput_cases[index].result = APUT_RESULT_FAIL;
+}
+
+/*
+ *Check if enabled amd pstate
+ */
+static void aput_check_enabled(u32 index)
+{
+ if (get_shared_mem())
+ aput_cases[index].result = APUT_RESULT_PASS;
+ else
+ aput_pstate_enable(index);
+}
+
+/*
+ * Check if the each performance values are reasonable.
+ * highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0
+ */
+static void aput_check_perf(u32 index)
+{
+ int cpu = 0, ret = 0;
+ u32 highest_perf = 0, nominal_perf = 0, lowest_nonlinear_perf = 0, lowest_perf = 0;
+ u64 cap1 = 0;
+ struct cppc_perf_caps cppc_perf;
+ struct cpufreq_policy *policy = NULL;
+ struct amd_cpudata *cpudata = NULL;
+
+ highest_perf = amd_get_highest_perf();
+
+ for_each_possible_cpu(cpu) {
+ policy = cpufreq_cpu_get(cpu);
+ if (!policy)
+ break;
+ cpudata = policy->driver_data;
+
+ if (get_shared_mem()) {
+ ret = cppc_get_perf_caps(cpu, &cppc_perf);
+ if (ret) {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s cppc_get_perf_caps ret=%d is error!\n", __func__, ret);
+ return;
+ }
+
+ nominal_perf = cppc_perf.nominal_perf;
+ lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf;
+ lowest_perf = cppc_perf.lowest_perf;
+ } else {
+ ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1);
+ if (ret) {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s read CPPC_CAP1 ret=%d is error!\n", __func__, ret);
+ return;
+ }
+
+ nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1);
+ lowest_nonlinear_perf = AMD_CPPC_LOWNONLIN_PERF(cap1);
+ lowest_perf = AMD_CPPC_LOWEST_PERF(cap1);
+ }
+
+ if ((highest_perf != READ_ONCE(cpudata->highest_perf)) ||
+ (nominal_perf != READ_ONCE(cpudata->nominal_perf)) ||
+ (lowest_nonlinear_perf != READ_ONCE(cpudata->lowest_nonlinear_perf)) ||
+ (lowest_perf != READ_ONCE(cpudata->lowest_perf))) {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s cpu%d highest=%d %d nominal=%d %d lowest_nonlinear=%d %d lowest=%d %d are not equal!\n",
+ __func__, cpu, highest_perf, cpudata->highest_perf,
+ nominal_perf, cpudata->nominal_perf,
+ lowest_nonlinear_perf, cpudata->lowest_nonlinear_perf,
+ lowest_perf, cpudata->lowest_perf);
+ return;
+ }
+
+ if (!((highest_perf >= nominal_perf) &&
+ (nominal_perf > lowest_nonlinear_perf) &&
+ (lowest_nonlinear_perf > lowest_perf) &&
+ (lowest_perf > 0))) {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s cpu%d highest=%d nominal=%d lowest_nonlinear=%d lowest=%d have error!\n",
+ __func__, cpu, highest_perf, nominal_perf,
+ lowest_nonlinear_perf, lowest_perf);
+ return;
+ }
+ }
+
+ aput_cases[index].result = APUT_RESULT_PASS;
+}
+
+/*
+ * Check if the each frequency values are reasonable.
+ * max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0
+ * check max freq when set support boost mode.
+ */
+static void aput_check_freq(u32 index)
+{
+ int cpu = 0;
+ struct cpufreq_policy *policy = NULL;
+ struct amd_cpudata *cpudata = NULL;
+
+ for_each_possible_cpu(cpu) {
+ policy = cpufreq_cpu_get(cpu);
+ if (!policy)
+ break;
+ cpudata = policy->driver_data;
+
+ if (!((cpudata->max_freq >= cpudata->nominal_freq) &&
+ (cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) &&
+ (cpudata->lowest_nonlinear_freq > cpudata->min_freq) &&
+ (cpudata->min_freq > 0))) {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s cpu%d max=%d nominal=%d lowest_nonlinear=%d min=%d have error!\n",
+ __func__, cpu, cpudata->max_freq, cpudata->nominal_freq,
+ cpudata->lowest_nonlinear_freq, cpudata->min_freq);
+ return;
+ }
+
+ if (cpudata->min_freq != policy->min) {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d have error!\n",
+ __func__, cpu, cpudata->min_freq, policy->min);
+ return;
+ }
+
+ if (cpudata->boost_supported) {
+ if ((policy->max == cpudata->max_freq) ||
+ (policy->max == cpudata->nominal_freq))
+ aput_cases[index].result = APUT_RESULT_PASS;
+ else {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s cpu%d policy_max=%d cpu_max=%d cpu_nominal=%d have error!\n",
+ __func__, cpu, policy->max, cpudata->max_freq,
+ cpudata->nominal_freq);
+ return;
+ }
+ } else {
+ aput_cases[index].result = APUT_RESULT_FAIL;
+ pr_err("%s cpu%d not support boost!\n", __func__, cpu);
+ return;
+ }
+ }
+}
+
+static void aput_do_test_case(void)
+{
+ u32 i = 0, arr_size = ARRAY_SIZE(aput_cases);
+
+ for (i = 0; i < arr_size; i++) {
+ pr_info("****** Begin %-5d\t %-20s\t ******\n", i+1, aput_cases[i].name);
+ aput_cases[i].func(i);
+ KSTM_CHECK_ZERO(aput_cases[i].result);
+ pr_info("****** End %-5d\t %-20s\t ******\n", i+1, aput_cases[i].name);
+ }
+}
+
+static void __init selftest(void)
+{
+ aput_do_test_case();
+}
+
+KSTM_MODULE_LOADERS(amd_pstate_ut);
+MODULE_AUTHOR("Meng Li <[email protected]>");
+MODULE_DESCRIPTION("Unit test for AMD P-state driver");
+MODULE_LICENSE("GPL");
--
2.25.1
On Thu, May 19, 2022 at 09:47:35PM +0800, Meng, Li (Jassmine) wrote:
> Add amd-pstate-ut module, which is conceptually out-of-tree module
> and provides ways for selftests/amd-pstate driver to test various
> kernel module-related functionality. This module will be expected by
> some of selftests to be present and loaded.
>
> Signed-off-by: Meng Li <[email protected]>
> Acked-by: Huang Rui <[email protected]>
> ---
> drivers/cpufreq/Kconfig.x86 | 6 +
> drivers/cpufreq/Makefile | 1 +
> drivers/cpufreq/amd-pstate-ut.c | 278 ++++++++++++++++++++++++++++++++
> 3 files changed, 285 insertions(+)
> create mode 100644 drivers/cpufreq/amd-pstate-ut.c
>
> diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
> index 55516043b656..37ba282cd156 100644
> --- a/drivers/cpufreq/Kconfig.x86
> +++ b/drivers/cpufreq/Kconfig.x86
> @@ -51,6 +51,12 @@ config X86_AMD_PSTATE
>
> If in doubt, say N.
>
> +config X86_AMD_PSTATE_UT
> + tristate "selftest for AMD Processor P-State driver"
> + depends on X86_AMD_PSTATE
I think we won't set X86_AMD_PSTATE as the depends of this module, because
even if the acpi-cpufreq is loaded, this module can test it out and tell
user the result.
ACPI and ACPI_PROCESSOR should the dependencies.
Thanks,
Ray
> + help
> + This kernel module is used for testing. It's safe to say M here.
> +
> config X86_ACPI_CPUFREQ
> tristate "ACPI Processor P-States driver"
> depends on ACPI_PROCESSOR
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 285de70af877..49b98c62c5af 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -30,6 +30,7 @@ amd_pstate-y := amd-pstate.o amd-pstate-trace.o
>
> obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
> obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o
> +obj-$(CONFIG_X86_AMD_PSTATE_UT) += amd-pstate-ut.o
> obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
> obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
> obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
> diff --git a/drivers/cpufreq/amd-pstate-ut.c b/drivers/cpufreq/amd-pstate-ut.c
> new file mode 100644
> index 000000000000..a510355b804e
> --- /dev/null
> +++ b/drivers/cpufreq/amd-pstate-ut.c
> @@ -0,0 +1,278 @@
> +// SPDX-License-Identifier: GPL-1.0-or-later
> +/*
> + * AMD Processor P-state Frequency Driver Unit Test
> + *
> + * Copyright (C) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
> + *
> + * Author: Meng Li <[email protected]>
> + *
> + * The AMD P-State Unit Test is a test module for testing the amd-pstate
> + * driver. 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.
> + *
> + * At present, it only implements the basic framework and some simple
> + * test cases. Next, 1) we will add a rst document. 2) we will add more
> + * test cases to improve the depth and coverage of the test.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include "../tools/testing/selftests/kselftest_module.h"
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/fs.h>
> +#include <linux/amd-pstate.h>
> +
> +#include <acpi/cppc_acpi.h>
> +
> +/*
> + * Abbreviations:
> + * aput: used as a shortform for AMD P-State unit test.
> + * It helps to keep variable names smaller, simpler
> + */
> +
> +KSTM_MODULE_GLOBALS();
> +
> +/*
> + * Kernel module for testing the AMD P-State unit test
> + */
> +enum aput_result {
> + APUT_RESULT_PASS,
> + APUT_RESULT_FAIL,
> + MAX_APUT_RESULT,
> +};
> +
> +struct aput_struct {
> + const char *name;
> + void (*func)(u32 index);
> + enum aput_result result;
> +};
> +
> +static void aput_acpi_cpc(u32 index);
> +static void aput_check_enabled(u32 index);
> +static void aput_check_perf(u32 index);
> +static void aput_check_freq(u32 index);
> +
> +static struct aput_struct aput_cases[] = {
> + {"acpi_cpc_valid", aput_acpi_cpc },
> + {"check_enabled", aput_check_enabled },
> + {"check_perf", aput_check_perf },
> + {"check_freq", aput_check_freq }
> +};
> +
> +static bool get_shared_mem(void)
> +{
> + bool result = false;
> + char buf[5] = {0};
> + struct file *filp = NULL;
> + loff_t pos = 0;
> + ssize_t ret;
> +
> + if (!boot_cpu_has(X86_FEATURE_CPPC)) {
> + filp = filp_open("/sys/module/amd_pstate/parameters/shared_mem", FMODE_PREAD, 0);
> + if (IS_ERR(filp))
> + pr_err("%s Open param file fail!\n", __func__);
> + else {
> + ret = kernel_read(filp, &buf, sizeof(buf), &pos);
> + if (ret < 0)
> + pr_err("%s ret=%ld unable to read from param file!\n",
> + __func__, ret);
> + filp_close(filp, NULL);
> + }
> +
> + if ('Y' == *buf)
> + result = true;
> + }
> +
> + return result;
> +}
> +
> +static void aput_acpi_cpc(u32 index)
> +{
> + if (acpi_cpc_valid())
> + aput_cases[index].result = APUT_RESULT_PASS;
> + else
> + aput_cases[index].result = APUT_RESULT_FAIL;
> +}
> +
> +static void aput_pstate_enable(u32 index)
> +{
> + int ret = 0;
> + u64 cppc_enable = 0;
> +
> + ret = rdmsrl_safe(MSR_AMD_CPPC_ENABLE, &cppc_enable);
> + if (ret) {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s rdmsrl_safe MSR_AMD_CPPC_ENABLE ret=%d is error!\n", __func__, ret);
> + return;
> + }
> + if (cppc_enable)
> + aput_cases[index].result = APUT_RESULT_PASS;
> + else
> + aput_cases[index].result = APUT_RESULT_FAIL;
> +}
> +
> +/*
> + *Check if enabled amd pstate
> + */
> +static void aput_check_enabled(u32 index)
> +{
> + if (get_shared_mem())
> + aput_cases[index].result = APUT_RESULT_PASS;
> + else
> + aput_pstate_enable(index);
> +}
> +
> +/*
> + * Check if the each performance values are reasonable.
> + * highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0
> + */
> +static void aput_check_perf(u32 index)
> +{
> + int cpu = 0, ret = 0;
> + u32 highest_perf = 0, nominal_perf = 0, lowest_nonlinear_perf = 0, lowest_perf = 0;
> + u64 cap1 = 0;
> + struct cppc_perf_caps cppc_perf;
> + struct cpufreq_policy *policy = NULL;
> + struct amd_cpudata *cpudata = NULL;
> +
> + highest_perf = amd_get_highest_perf();
> +
> + for_each_possible_cpu(cpu) {
> + policy = cpufreq_cpu_get(cpu);
> + if (!policy)
> + break;
> + cpudata = policy->driver_data;
> +
> + if (get_shared_mem()) {
> + ret = cppc_get_perf_caps(cpu, &cppc_perf);
> + if (ret) {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s cppc_get_perf_caps ret=%d is error!\n", __func__, ret);
> + return;
> + }
> +
> + nominal_perf = cppc_perf.nominal_perf;
> + lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf;
> + lowest_perf = cppc_perf.lowest_perf;
> + } else {
> + ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1);
> + if (ret) {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s read CPPC_CAP1 ret=%d is error!\n", __func__, ret);
> + return;
> + }
> +
> + nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1);
> + lowest_nonlinear_perf = AMD_CPPC_LOWNONLIN_PERF(cap1);
> + lowest_perf = AMD_CPPC_LOWEST_PERF(cap1);
> + }
> +
> + if ((highest_perf != READ_ONCE(cpudata->highest_perf)) ||
> + (nominal_perf != READ_ONCE(cpudata->nominal_perf)) ||
> + (lowest_nonlinear_perf != READ_ONCE(cpudata->lowest_nonlinear_perf)) ||
> + (lowest_perf != READ_ONCE(cpudata->lowest_perf))) {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s cpu%d highest=%d %d nominal=%d %d lowest_nonlinear=%d %d lowest=%d %d are not equal!\n",
> + __func__, cpu, highest_perf, cpudata->highest_perf,
> + nominal_perf, cpudata->nominal_perf,
> + lowest_nonlinear_perf, cpudata->lowest_nonlinear_perf,
> + lowest_perf, cpudata->lowest_perf);
> + return;
> + }
> +
> + if (!((highest_perf >= nominal_perf) &&
> + (nominal_perf > lowest_nonlinear_perf) &&
> + (lowest_nonlinear_perf > lowest_perf) &&
> + (lowest_perf > 0))) {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s cpu%d highest=%d nominal=%d lowest_nonlinear=%d lowest=%d have error!\n",
> + __func__, cpu, highest_perf, nominal_perf,
> + lowest_nonlinear_perf, lowest_perf);
> + return;
> + }
> + }
> +
> + aput_cases[index].result = APUT_RESULT_PASS;
> +}
> +
> +/*
> + * Check if the each frequency values are reasonable.
> + * max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0
> + * check max freq when set support boost mode.
> + */
> +static void aput_check_freq(u32 index)
> +{
> + int cpu = 0;
> + struct cpufreq_policy *policy = NULL;
> + struct amd_cpudata *cpudata = NULL;
> +
> + for_each_possible_cpu(cpu) {
> + policy = cpufreq_cpu_get(cpu);
> + if (!policy)
> + break;
> + cpudata = policy->driver_data;
> +
> + if (!((cpudata->max_freq >= cpudata->nominal_freq) &&
> + (cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) &&
> + (cpudata->lowest_nonlinear_freq > cpudata->min_freq) &&
> + (cpudata->min_freq > 0))) {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s cpu%d max=%d nominal=%d lowest_nonlinear=%d min=%d have error!\n",
> + __func__, cpu, cpudata->max_freq, cpudata->nominal_freq,
> + cpudata->lowest_nonlinear_freq, cpudata->min_freq);
> + return;
> + }
> +
> + if (cpudata->min_freq != policy->min) {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d have error!\n",
> + __func__, cpu, cpudata->min_freq, policy->min);
> + return;
> + }
> +
> + if (cpudata->boost_supported) {
> + if ((policy->max == cpudata->max_freq) ||
> + (policy->max == cpudata->nominal_freq))
> + aput_cases[index].result = APUT_RESULT_PASS;
> + else {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s cpu%d policy_max=%d cpu_max=%d cpu_nominal=%d have error!\n",
> + __func__, cpu, policy->max, cpudata->max_freq,
> + cpudata->nominal_freq);
> + return;
> + }
> + } else {
> + aput_cases[index].result = APUT_RESULT_FAIL;
> + pr_err("%s cpu%d not support boost!\n", __func__, cpu);
> + return;
> + }
> + }
> +}
> +
> +static void aput_do_test_case(void)
> +{
> + u32 i = 0, arr_size = ARRAY_SIZE(aput_cases);
> +
> + for (i = 0; i < arr_size; i++) {
> + pr_info("****** Begin %-5d\t %-20s\t ******\n", i+1, aput_cases[i].name);
> + aput_cases[i].func(i);
> + KSTM_CHECK_ZERO(aput_cases[i].result);
> + pr_info("****** End %-5d\t %-20s\t ******\n", i+1, aput_cases[i].name);
> + }
> +}
> +
> +static void __init selftest(void)
> +{
> + aput_do_test_case();
> +}
> +
> +KSTM_MODULE_LOADERS(amd_pstate_ut);
> +MODULE_AUTHOR("Meng Li <[email protected]>");
> +MODULE_DESCRIPTION("Unit test for AMD P-state driver");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>
Hi Meng,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on shuah-kselftest/next]
[also build test WARNING on rafael-pm/linux-next linux/master linus/master v5.18-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Meng-Li/Add-unit-test-module-for-AMD-P-State-driver/20220519-215444
base: https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git next
config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20220520/[email protected]/config)
compiler: gcc-11 (Debian 11.3.0-1) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/5a00a68d142a32f76cf2e770d75463802273e7ed
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Meng-Li/Add-unit-test-module-for-AMD-P-State-driver/20220519-215444
git checkout 5a00a68d142a32f76cf2e770d75463802273e7ed
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/cpufreq/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
In file included from include/linux/kernel.h:29,
from arch/x86/include/asm/percpu.h:27,
from arch/x86/include/asm/current.h:6,
from arch/x86/include/asm/processor.h:17,
from arch/x86/include/asm/timex.h:5,
from include/linux/timex.h:65,
from include/linux/time32.h:13,
from include/linux/time.h:60,
from include/linux/stat.h:19,
from include/linux/module.h:13,
from include/../tools/testing/selftests/kselftest_module.h:5,
from drivers/cpufreq/amd-pstate-ut.c:23:
drivers/cpufreq/amd-pstate-ut.c: In function 'get_shared_mem':
>> include/linux/kern_levels.h:5:25: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'ssize_t' {aka 'int'} [-Wformat=]
5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
| ^~~~~~
include/linux/printk.h:418:25: note: in definition of macro 'printk_index_wrap'
418 | _p_func(_fmt, ##__VA_ARGS__); \
| ^~~~
include/linux/printk.h:489:9: note: in expansion of macro 'printk'
489 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~
include/linux/kern_levels.h:11:25: note: in expansion of macro 'KERN_SOH'
11 | #define KERN_ERR KERN_SOH "3" /* error conditions */
| ^~~~~~~~
include/linux/printk.h:489:16: note: in expansion of macro 'KERN_ERR'
489 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~~
drivers/cpufreq/amd-pstate-ut.c:83:33: note: in expansion of macro 'pr_err'
83 | pr_err("%s ret=%ld unable to read from param file!\n",
| ^~~~~~
vim +5 include/linux/kern_levels.h
314ba3520e513a Joe Perches 2012-07-30 4
04d2c8c83d0e3a Joe Perches 2012-07-30 @5 #define KERN_SOH "\001" /* ASCII Start Of Header */
04d2c8c83d0e3a Joe Perches 2012-07-30 6 #define KERN_SOH_ASCII '\001'
04d2c8c83d0e3a Joe Perches 2012-07-30 7
--
0-DAY CI Kernel Test Service
https://01.org/lkp
On 5/19/22 7:47 AM, Meng Li wrote:
> Add amd-pstate test trigger in kselftest, it will load/unload
> amd-pstate-ut module to test some cases etc.
>
> Signed-off-by: Meng Li <[email protected]>
> Acked-by: Huang Rui <[email protected]>
> ---
> tools/testing/selftests/Makefile | 1 +
> tools/testing/selftests/amd-pstate/Makefile | 8 +++++
> .../selftests/amd-pstate/amd-pstate-ut.sh | 34 +++++++++++++++++++
> tools/testing/selftests/amd-pstate/config | 1 +
> 4 files changed, 44 insertions(+)
> create mode 100644 tools/testing/selftests/amd-pstate/Makefile
> create mode 100755 tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> create mode 100644 tools/testing/selftests/amd-pstate/config
>
> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
> index 2319ec87f53d..975c13368286 100644
> --- a/tools/testing/selftests/Makefile
> +++ b/tools/testing/selftests/Makefile
> @@ -1,5 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0
> TARGETS += alsa
> +TARGETS += amd-pstate
> TARGETS += arm64
> TARGETS += bpf
> TARGETS += breakpoints
> diff --git a/tools/testing/selftests/amd-pstate/Makefile b/tools/testing/selftests/amd-pstate/Makefile
> new file mode 100644
> index 000000000000..e1432112fb70
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/Makefile
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Makefile for amd-pstate/ function selftests
> +
> +TEST_PROGS := amd-pstate-ut.sh
> +
> +include ../lib.mk
> +
> +$(TEST_GEN_FILES): $(HEADERS)
Do you still need this?
> diff --git a/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh b/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> new file mode 100755
> index 000000000000..970f7a76c7d5
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
> @@ -0,0 +1,34 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# amd-pstate-ut is a test module for testing the amd-pstate driver.
> +# (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
> +
> +if ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then
This can be simpler - see prctl/Makefile or other tests that do arch
checks. Also does this test run on non-amd x86_64 systems?
> + echo "$0 # Skipped: Test can only run on x86 architectures."
All x86 or x86_64 AMD systems? Does this run on Intel systems?
> + exit $ksft_skip
> +fi
> +
> +msg="Skip all tests:"
> +if [ ! -w /dev ]; then
> + echo $msg please run this as root >&2
> + 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
> +
> +$(dirname $0)/../kselftest/module.sh "amd-pstate-ut" amd-pstate-ut
What does this do?
Has this script been updated after moving the module to drivers/cpufreq?
Also doesn't this script need to to load the amd_pstate_ut module?
Please take a look at user/test_user_copy.sh for example on modprobe
checks and appropriate test exit codes
> diff --git a/tools/testing/selftests/amd-pstate/config b/tools/testing/selftests/amd-pstate/config
> new file mode 100644
> index 000000000000..f43103c9adc4
> --- /dev/null
> +++ b/tools/testing/selftests/amd-pstate/config
> @@ -0,0 +1 @@
> +CONFIG_X86_AMD_PSTATE_UT=m
>
thanks,
-- Shuah