linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Add unit test module for AMD P-State driver
@ 2022-04-13  9:05 Meng Li
  2022-04-13  9:05 ` [PATCH 1/3] cpufreq: amd-pstate: Expose struct amd_cpudata Meng Li
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Meng Li @ 2022-04-13  9:05 UTC (permalink / raw)
  To: Shuah Khan, Rafael J . Wysocki, Huang Rui, linux-pm
  Cc: Nathan Fontenot, Deepak Sharma, Alex Deucher, Mario Limonciello,
	Jinzhou Su, Perry Yuan, Xiaojian Du, Viresh Kumar,
	Borislav Petkov, linux-kernel, Meng Li

Hi all:

AMD P-State unit test(amd_pstate_testmod) is a kernel module for testing
the functions of amd-pstate driver.
It could import as a module to launch some test tasks.

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_testmod module and tie it into kselftest.

For exmaple: 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, its test cases are very simple, and the corresponding test
cases will continue to be added later to improve the test coverage.

See patch series in below git repo:
V1: https://lore.kernel.org/linux-pm/20220323071502.2674156-1-li.meng@amd.com/

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.

Thanks,
Jasmine

Meng Li (3):
  cpufreq: amd-pstate: Expose struct amd_cpudata
  selftests: cpufreq: Add wapper script for test AMD P-State
  selftests: cpufreq: Add amd_pstate_testmod kernel module for testing

 MAINTAINERS                                   |   1 +
 drivers/cpufreq/amd-pstate.c                  |  60 +---
 include/linux/amd-pstate.h                    |  74 +++++
 tools/testing/selftests/cpufreq/Makefile      |   2 +-
 .../selftests/cpufreq/amd_pstate_testmod.sh   |   4 +
 .../cpufreq/amd_pstate_testmod/Makefile       |  20 ++
 .../amd_pstate_testmod/amd_pstate_testmod.c   | 302 ++++++++++++++++++
 tools/testing/selftests/cpufreq/config        |   1 +
 8 files changed, 404 insertions(+), 60 deletions(-)
 create mode 100644 include/linux/amd-pstate.h
 create mode 100755 tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
 create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
 create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c

-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/3] cpufreq: amd-pstate: Expose struct amd_cpudata
  2022-04-13  9:05 [PATCH v2 0/3] Add unit test module for AMD P-State driver Meng Li
@ 2022-04-13  9:05 ` Meng Li
  2022-04-17  2:09   ` Huang Rui
  2022-04-13  9:05 ` [PATCH 2/3] selftests: cpufreq: Add wapper script for test AMD P-State Meng Li
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Meng Li @ 2022-04-13  9:05 UTC (permalink / raw)
  To: Shuah Khan, Rafael J . Wysocki, Huang Rui, linux-pm
  Cc: Nathan Fontenot, Deepak Sharma, Alex Deucher, Mario Limonciello,
	Jinzhou Su, Perry Yuan, Xiaojian Du, Viresh Kumar,
	Borislav Petkov, linux-kernel, Meng Li

Expose struct amd_cpudata to AMD P-State unit test module.

This data struct will be used on the following AMD P-State unit test
(amd-pstate-ut) module. The amd-pstate-ut module can get some AMD
infomations by this data struct. For example: highest perf,
nominal perf, boost supported etc.

Signed-off-by: Meng Li <li.meng@amd.com>
---
 MAINTAINERS                  |  1 +
 drivers/cpufreq/amd-pstate.c | 60 +----------------------------
 include/linux/amd-pstate.h   | 74 ++++++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+), 59 deletions(-)
 create mode 100644 include/linux/amd-pstate.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9832b607e2e2..f108e83ba851 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1003,6 +1003,7 @@ S:	Supported
 F:	Documentation/admin-guide/pm/amd-pstate.rst
 F:	drivers/cpufreq/amd-pstate*
 F:	tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
+F:	include/linux/amd-pstate.h
 
 AMD PTDMA DRIVER
 M:	Sanjay R Mehta <sanju.mehta@amd.com>
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 7be38bc6a673..5f7a00a64f76 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -36,6 +36,7 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/static_call.h>
+#include <linux/amd-pstate.h>
 
 #include <acpi/processor.h>
 #include <acpi/cppc_acpi.h>
@@ -65,65 +66,6 @@ MODULE_PARM_DESC(shared_mem,
 
 static struct cpufreq_driver amd_pstate_driver;
 
-/**
- * struct  amd_aperf_mperf
- * @aperf: actual performance frequency clock count
- * @mperf: maximum performance frequency clock count
- * @tsc:   time stamp counter
- */
-struct amd_aperf_mperf {
-	u64 aperf;
-	u64 mperf;
-	u64 tsc;
-};
-
-/**
- * struct amd_cpudata - private CPU data for AMD P-State
- * @cpu: CPU number
- * @req: constraint request to apply
- * @cppc_req_cached: cached performance request hints
- * @highest_perf: the maximum performance an individual processor may reach,
- *		  assuming ideal conditions
- * @nominal_perf: the maximum sustained performance level of the processor,
- *		  assuming ideal operating conditions
- * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power
- *			   savings are achieved
- * @lowest_perf: the absolute lowest performance level of the processor
- * @max_freq: the frequency that mapped to highest_perf
- * @min_freq: the frequency that mapped to lowest_perf
- * @nominal_freq: the frequency that mapped to nominal_perf
- * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
- * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
- * @prev: Last Aperf/Mperf/tsc count value read from register
- * @freq: current cpu frequency value
- * @boost_supported: check whether the Processor or SBIOS supports boost mode
- *
- * The amd_cpudata is key private data for each CPU thread in AMD P-State, and
- * represents all the attributes and goals that AMD P-State requests at runtime.
- */
-struct amd_cpudata {
-	int	cpu;
-
-	struct	freq_qos_request req[2];
-	u64	cppc_req_cached;
-
-	u32	highest_perf;
-	u32	nominal_perf;
-	u32	lowest_nonlinear_perf;
-	u32	lowest_perf;
-
-	u32	max_freq;
-	u32	min_freq;
-	u32	nominal_freq;
-	u32	lowest_nonlinear_freq;
-
-	struct amd_aperf_mperf cur;
-	struct amd_aperf_mperf prev;
-
-	u64 freq;
-	bool	boost_supported;
-};
-
 static inline int pstate_enable(bool enable)
 {
 	return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable);
diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h
new file mode 100644
index 000000000000..790b04c9000b
--- /dev/null
+++ b/include/linux/amd-pstate.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * linux/include/linux/amd-pstate.h
+ *
+ * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
+ * Author: Meng Li <li.meng@amd.com>
+ */
+#ifndef _LINUX_AMD_PSTATE_H
+#define _LINUX_AMD_PSTATE_H
+
+#include <linux/pm_qos.h>
+/*********************************************************************
+ *                        AMD P-state INTERFACE                       *
+ *********************************************************************/
+/**
+ * struct  amd_aperf_mperf
+ * @aperf: actual performance frequency clock count
+ * @mperf: maximum performance frequency clock count
+ * @tsc:   time stamp counter
+ */
+struct amd_aperf_mperf {
+	u64 aperf;
+	u64 mperf;
+	u64 tsc;
+};
+
+/**
+ * struct amd_cpudata - private CPU data for AMD P-State
+ * @cpu: CPU number
+ * @req: constraint request to apply
+ * @cppc_req_cached: cached performance request hints
+ * @highest_perf: the maximum performance an individual processor may reach,
+ *		  assuming ideal conditions
+ * @nominal_perf: the maximum sustained performance level of the processor,
+ *		  assuming ideal operating conditions
+ * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power
+ *			   savings are achieved
+ * @lowest_perf: the absolute lowest performance level of the processor
+ * @max_freq: the frequency that mapped to highest_perf
+ * @min_freq: the frequency that mapped to lowest_perf
+ * @nominal_freq: the frequency that mapped to nominal_perf
+ * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
+ * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
+ * @prev: Last Aperf/Mperf/tsc count value read from register
+ * @freq: current cpu frequency value
+ * @boost_supported: check whether the Processor or SBIOS supports boost mode
+ *
+ * The amd_cpudata is key private data for each CPU thread in AMD P-State, and
+ * represents all the attributes and goals that AMD P-State requests at runtime.
+ */
+struct amd_cpudata {
+	int	cpu;
+
+	struct	freq_qos_request req[2];
+	u64	cppc_req_cached;
+
+	u32	highest_perf;
+	u32	nominal_perf;
+	u32	lowest_nonlinear_perf;
+	u32	lowest_perf;
+
+	u32	max_freq;
+	u32	min_freq;
+	u32	nominal_freq;
+	u32	lowest_nonlinear_freq;
+
+	struct amd_aperf_mperf cur;
+	struct amd_aperf_mperf prev;
+
+	u64	freq;
+	bool	boost_supported;
+};
+
+#endif /* _LINUX_AMD_PSTATE_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] selftests: cpufreq: Add wapper script for test AMD P-State
  2022-04-13  9:05 [PATCH v2 0/3] Add unit test module for AMD P-State driver Meng Li
  2022-04-13  9:05 ` [PATCH 1/3] cpufreq: amd-pstate: Expose struct amd_cpudata Meng Li
@ 2022-04-13  9:05 ` Meng Li
  2022-04-13 19:55   ` Nathan Fontenot
  2022-04-13  9:05 ` [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing Meng Li
  2022-04-13 15:41 ` [PATCH v2 0/3] Add unit test module for AMD P-State driver Rafael J. Wysocki
  3 siblings, 1 reply; 10+ messages in thread
From: Meng Li @ 2022-04-13  9:05 UTC (permalink / raw)
  To: Shuah Khan, Rafael J . Wysocki, Huang Rui, linux-pm
  Cc: Nathan Fontenot, Deepak Sharma, Alex Deucher, Mario Limonciello,
	Jinzhou Su, Perry Yuan, Xiaojian Du, Viresh Kumar,
	Borislav Petkov, linux-kernel, Meng Li

Adds a wrapper shell script for the amd_pstate_testmod module.

Signed-off-by: Meng Li <li.meng@amd.com>
---
 tools/testing/selftests/cpufreq/Makefile              | 2 +-
 tools/testing/selftests/cpufreq/amd_pstate_testmod.sh | 4 ++++
 tools/testing/selftests/cpufreq/config                | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)
 create mode 100755 tools/testing/selftests/cpufreq/amd_pstate_testmod.sh

diff --git a/tools/testing/selftests/cpufreq/Makefile b/tools/testing/selftests/cpufreq/Makefile
index c86ca8342222..c32adc59a1f4 100644
--- a/tools/testing/selftests/cpufreq/Makefile
+++ b/tools/testing/selftests/cpufreq/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 all:
 
-TEST_PROGS := main.sh
+TEST_PROGS := main.sh amd_pstate_testmod.sh
 TEST_FILES := cpu.sh cpufreq.sh governor.sh module.sh special-tests.sh
 
 include ../lib.mk
diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod.sh b/tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
new file mode 100755
index 000000000000..5398ad568885
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# Tests the AMD P-State unit test infrastructure using amd_pstate_testmod kernel module.
+$(dirname $0)/../kselftest/module.sh "amd_pstate_testmod" amd_pstate_testmod
diff --git a/tools/testing/selftests/cpufreq/config b/tools/testing/selftests/cpufreq/config
index 75e900793e8a..374a8adbb34c 100644
--- a/tools/testing/selftests/cpufreq/config
+++ b/tools/testing/selftests/cpufreq/config
@@ -13,3 +13,4 @@ CONFIG_DEBUG_LOCK_ALLOC=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_LOCKDEP=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_AMD_PSTATE_TESTMOD=m
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing
  2022-04-13  9:05 [PATCH v2 0/3] Add unit test module for AMD P-State driver Meng Li
  2022-04-13  9:05 ` [PATCH 1/3] cpufreq: amd-pstate: Expose struct amd_cpudata Meng Li
  2022-04-13  9:05 ` [PATCH 2/3] selftests: cpufreq: Add wapper script for test AMD P-State Meng Li
@ 2022-04-13  9:05 ` Meng Li
  2022-04-13 20:16   ` Nathan Fontenot
  2022-04-17 14:54   ` Huang Rui
  2022-04-13 15:41 ` [PATCH v2 0/3] Add unit test module for AMD P-State driver Rafael J. Wysocki
  3 siblings, 2 replies; 10+ messages in thread
From: Meng Li @ 2022-04-13  9:05 UTC (permalink / raw)
  To: Shuah Khan, Rafael J . Wysocki, Huang Rui, linux-pm
  Cc: Nathan Fontenot, Deepak Sharma, Alex Deucher, Mario Limonciello,
	Jinzhou Su, Perry Yuan, Xiaojian Du, Viresh Kumar,
	Borislav Petkov, linux-kernel, Meng Li

Add amd_pstate_testmod module, which is conceptually out-of-tree module and
provides ways for selftests/cpufreq 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 <li.meng@amd.com>
---
 .../cpufreq/amd_pstate_testmod/Makefile       |  20 ++
 .../amd_pstate_testmod/amd_pstate_testmod.c   | 302 ++++++++++++++++++
 2 files changed, 322 insertions(+)
 create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
 create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c

diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile b/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
new file mode 100644
index 000000000000..8a5596cb2c18
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
@@ -0,0 +1,20 @@
+AMD_PSTATE_TESTMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
+KDIR ?= $(abspath $(AMD_PSATE_TESTMOD_DIR)/../../../../..)
+
+ifeq ($(V),1)
+Q =
+else
+Q = @
+endif
+
+MODULES = amd_pstate_testmod.ko
+
+obj-m += amd_pstate_testmod.o
+CFLAGS_amd_pstate_testmod.o = -I$(src)
+
+all:
+	+$(Q)make -C $(KDIR) M=$(AMD_PSTATE_TESTMOD_DIR) modules
+
+clean:
+	+$(Q)make -C $(KDIR) M=$(AMD_PSTATE_TESTMOD_DIR) clean
+
diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c b/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
new file mode 100644
index 000000000000..a892cecf19da
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
@@ -0,0 +1,302 @@
+// 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 <li.meng@amd.com>
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "../../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,	//0
+	APUT_RESULT_FAIL,	//
+	MAX_APUT_RESULT,
+};
+
+struct aput_struct {
+	const char *name;
+	void (*func)(u32 index);
+	enum aput_result result;
+};
+
+static void aput_x86_vendor(u32 index);
+static void aput_acpi_cpc(u32 index);
+static void aput_modprobed_driver(u32 index);
+static void aput_capability_check(u32 index);
+static void aput_enable(u32 index);
+static void aput_init_perf(u32 index);
+static void aput_support_boost(u32 index);
+
+static struct aput_struct aput_cases[] = {
+	{"x86_vendor",          aput_x86_vendor          },
+	{"acpi_cpc_valid",      aput_acpi_cpc            },
+	{"modprobed_driver",    aput_modprobed_driver    },
+	{"capability_check",    aput_capability_check    },
+	{"enable",              aput_enable              },
+	{"init_perf",           aput_init_perf           },
+	{"support_boost",       aput_support_boost       }
+};
+
+static bool get_shared_mem(void)
+{
+	bool result = false;
+	char buf[5] = {0};
+	struct file *filp = NULL;
+	loff_t pos = 0;
+	ssize_t ret;
+
+	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_x86_vendor(u32 index)
+{
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+	{
+		aput_cases[index].result = APUT_RESULT_PASS;
+	}
+	else
+	{
+		aput_cases[index].result = APUT_RESULT_FAIL;
+	}
+}
+
+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_modprobed_driver(u32 index)
+{
+	if (cpufreq_get_current_driver())
+	{
+		aput_cases[index].result = APUT_RESULT_PASS;
+	}
+	else
+	{
+		aput_cases[index].result = APUT_RESULT_FAIL;
+	}
+}
+
+static void aput_capability_check(u32 index)
+{
+	if (boot_cpu_has(X86_FEATURE_CPPC))
+	{
+		aput_cases[index].result = APUT_RESULT_PASS;
+	}
+	else
+	{
+		//shared memory
+		if (get_shared_mem())
+		{
+			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;
+	}
+}
+
+static void aput_enable(u32 index)
+{
+	if (get_shared_mem())
+	{
+		//not check
+		aput_cases[index].result = APUT_RESULT_PASS;
+	}
+	else
+	{
+		aput_pstate_enable(index);
+	}
+}
+
+static void aput_init_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;
+
+	//get perf
+	highest_perf = amd_get_highest_perf();
+
+	for_each_possible_cpu(cpu)
+	{
+		//get amd cpudata
+		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 rdmsrl_safe_on_cpu MSR_AMD_CPPC_CAP1 ret=%d is error! \n", __func__, ret);
+				return;
+			}
+
+			//get perf from MSR
+			nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1);
+			lowest_nonlinear_perf = AMD_CPPC_LOWNONLIN_PERF(cap1);
+			lowest_perf = AMD_CPPC_LOWEST_PERF(cap1);
+		}
+
+		//check highest_perf,nominal_perf,lowest_nonlinear_perf
+		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_perf=%d %d nominal_perf=%d %d lowest_nonlinear_perf=%d %d lowest_perf=%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;
+		}
+	}
+
+	aput_cases[index].result = APUT_RESULT_PASS;
+}
+
+static void aput_support_boost(u32 index)
+{
+	int cpu = 0;
+	struct cpufreq_policy *policy = NULL;
+        struct amd_cpudata *cpudata = NULL;
+
+	for_each_possible_cpu(cpu)
+	{
+		//get amd cpudata
+		policy = cpufreq_cpu_get(cpu);
+		if (!policy)
+			break;
+		cpudata = policy->driver_data;
+
+		if (READ_ONCE(cpudata->boost_supported))
+		{
+			aput_cases[index].result = APUT_RESULT_PASS;
+		}
+		else
+		{
+			aput_cases[index].result = APUT_RESULT_FAIL;
+			break;
+		}
+	}
+}
+
+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_testmod);
+MODULE_AUTHOR("Meng Li <li.meng@amd.com>");
+MODULE_DESCRIPTION("Unit test for AMD P-state driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 0/3] Add unit test module for AMD P-State driver
  2022-04-13  9:05 [PATCH v2 0/3] Add unit test module for AMD P-State driver Meng Li
                   ` (2 preceding siblings ...)
  2022-04-13  9:05 ` [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing Meng Li
@ 2022-04-13 15:41 ` Rafael J. Wysocki
  2022-04-17  1:38   ` Huang Rui
  3 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki @ 2022-04-13 15:41 UTC (permalink / raw)
  To: Meng Li
  Cc: Shuah Khan, Rafael J . Wysocki, Huang Rui, Linux PM,
	Nathan Fontenot, Deepak Sharma, Alex Deucher, Mario Limonciello,
	Jinzhou Su, Perry Yuan, Xiaojian Du, Viresh Kumar,
	Borislav Petkov, Linux Kernel Mailing List

On Wed, Apr 13, 2022 at 11:06 AM Meng Li <li.meng@amd.com> wrote:
>
> Hi all:
>
> AMD P-State unit test(amd_pstate_testmod) is a kernel module for testing
> the functions of amd-pstate driver.
> It could import as a module to launch some test tasks.
>
> 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_testmod module and tie it into kselftest.
>
> For exmaple: 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, its test cases are very simple, and the corresponding test
> cases will continue to be added later to improve the test coverage.
>
> See patch series in below git repo:
> V1: https://lore.kernel.org/linux-pm/20220323071502.2674156-1-li.meng@amd.com/
>
> 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.
>
> Thanks,
> Jasmine
>
> Meng Li (3):
>   cpufreq: amd-pstate: Expose struct amd_cpudata

Please collect an ACK from Ray for this one as per MAINTAINERS and I
will leave the series to Shuah as it is selftests mostly.

Thanks!

>   selftests: cpufreq: Add wapper script for test AMD P-State
>   selftests: cpufreq: Add amd_pstate_testmod kernel module for testing
>
>  MAINTAINERS                                   |   1 +
>  drivers/cpufreq/amd-pstate.c                  |  60 +---
>  include/linux/amd-pstate.h                    |  74 +++++
>  tools/testing/selftests/cpufreq/Makefile      |   2 +-
>  .../selftests/cpufreq/amd_pstate_testmod.sh   |   4 +
>  .../cpufreq/amd_pstate_testmod/Makefile       |  20 ++
>  .../amd_pstate_testmod/amd_pstate_testmod.c   | 302 ++++++++++++++++++
>  tools/testing/selftests/cpufreq/config        |   1 +
>  8 files changed, 404 insertions(+), 60 deletions(-)
>  create mode 100644 include/linux/amd-pstate.h
>  create mode 100755 tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
>  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
>  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
>
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] selftests: cpufreq: Add wapper script for test AMD P-State
  2022-04-13  9:05 ` [PATCH 2/3] selftests: cpufreq: Add wapper script for test AMD P-State Meng Li
@ 2022-04-13 19:55   ` Nathan Fontenot
  0 siblings, 0 replies; 10+ messages in thread
From: Nathan Fontenot @ 2022-04-13 19:55 UTC (permalink / raw)
  To: Meng Li, Shuah Khan, Rafael J . Wysocki, Huang Rui, linux-pm
  Cc: Nathan Fontenot, Deepak Sharma, Alex Deucher, Mario Limonciello,
	Jinzhou Su, Perry Yuan, Xiaojian Du, Viresh Kumar,
	Borislav Petkov, linux-kernel

On 4/13/22 04:05, Meng Li wrote:
> Adds a wrapper shell script for the amd_pstate_testmod module.
> 
> Signed-off-by: Meng Li <li.meng@amd.com>
> ---
>  tools/testing/selftests/cpufreq/Makefile              | 2 +-
>  tools/testing/selftests/cpufreq/amd_pstate_testmod.sh | 4 ++++
>  tools/testing/selftests/cpufreq/config                | 1 +
>  3 files changed, 6 insertions(+), 1 deletion(-)
>  create mode 100755 tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
> 
> diff --git a/tools/testing/selftests/cpufreq/Makefile b/tools/testing/selftests/cpufreq/Makefile
> index c86ca8342222..c32adc59a1f4 100644
> --- a/tools/testing/selftests/cpufreq/Makefile
> +++ b/tools/testing/selftests/cpufreq/Makefile
> @@ -1,7 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  all:
>  
> -TEST_PROGS := main.sh
> +TEST_PROGS := main.sh amd_pstate_testmod.sh

Instead of making the amd-pstate testing a separate test program, should this
be part of the main.sh testing program?

Perhaps adding a "driver" test function that can check for the amd-pstate driver
being in use and run the test module.

-Nathan

>  TEST_FILES := cpu.sh cpufreq.sh governor.sh module.sh special-tests.sh
>  
>  include ../lib.mk
> diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod.sh b/tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
> new file mode 100755
> index 000000000000..5398ad568885
> --- /dev/null
> +++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
> @@ -0,0 +1,4 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +# Tests the AMD P-State unit test infrastructure using amd_pstate_testmod kernel module.
> +$(dirname $0)/../kselftest/module.sh "amd_pstate_testmod" amd_pstate_testmod
> diff --git a/tools/testing/selftests/cpufreq/config b/tools/testing/selftests/cpufreq/config
> index 75e900793e8a..374a8adbb34c 100644
> --- a/tools/testing/selftests/cpufreq/config
> +++ b/tools/testing/selftests/cpufreq/config
> @@ -13,3 +13,4 @@ CONFIG_DEBUG_LOCK_ALLOC=y
>  CONFIG_PROVE_LOCKING=y
>  CONFIG_LOCKDEP=y
>  CONFIG_DEBUG_ATOMIC_SLEEP=y
> +CONFIG_AMD_PSTATE_TESTMOD=m

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing
  2022-04-13  9:05 ` [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing Meng Li
@ 2022-04-13 20:16   ` Nathan Fontenot
  2022-04-17 14:54   ` Huang Rui
  1 sibling, 0 replies; 10+ messages in thread
From: Nathan Fontenot @ 2022-04-13 20:16 UTC (permalink / raw)
  To: Meng Li, Shuah Khan, Rafael J . Wysocki, Huang Rui, linux-pm
  Cc: Nathan Fontenot, Deepak Sharma, Alex Deucher, Mario Limonciello,
	Jinzhou Su, Perry Yuan, Xiaojian Du, Viresh Kumar,
	Borislav Petkov, linux-kernel

On 4/13/22 04:05, Meng Li wrote:
> Add amd_pstate_testmod module, which is conceptually out-of-tree module and
> provides ways for selftests/cpufreq 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 <li.meng@amd.com>
> ---
>  .../cpufreq/amd_pstate_testmod/Makefile       |  20 ++
>  .../amd_pstate_testmod/amd_pstate_testmod.c   | 302 ++++++++++++++++++
>  2 files changed, 322 insertions(+)
>  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
>  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
> 
> diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile b/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
> new file mode 100644
> index 000000000000..8a5596cb2c18
> --- /dev/null
> +++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
> @@ -0,0 +1,20 @@
> +AMD_PSTATE_TESTMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
> +KDIR ?= $(abspath $(AMD_PSATE_TESTMOD_DIR)/../../../../..)
> +
> +ifeq ($(V),1)
> +Q =
> +else
> +Q = @
> +endif
> +
> +MODULES = amd_pstate_testmod.ko
> +
> +obj-m += amd_pstate_testmod.o
> +CFLAGS_amd_pstate_testmod.o = -I$(src)
> +
> +all:
> +	+$(Q)make -C $(KDIR) M=$(AMD_PSTATE_TESTMOD_DIR) modules
> +
> +clean:
> +	+$(Q)make -C $(KDIR) M=$(AMD_PSTATE_TESTMOD_DIR) clean
> +
> diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c b/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
> new file mode 100644
> index 000000000000..a892cecf19da
> --- /dev/null
> +++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
> @@ -0,0 +1,302 @@
> +// 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 <li.meng@amd.com>
> + *
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include "../../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,	//0
> +	APUT_RESULT_FAIL,	//
> +	MAX_APUT_RESULT,
> +};
> +
> +struct aput_struct {
> +	const char *name;
> +	void (*func)(u32 index);
> +	enum aput_result result;
> +};
> +
> +static void aput_x86_vendor(u32 index);
> +static void aput_acpi_cpc(u32 index);
> +static void aput_modprobed_driver(u32 index);
> +static void aput_capability_check(u32 index);
> +static void aput_enable(u32 index);
> +static void aput_init_perf(u32 index);
> +static void aput_support_boost(u32 index);
> +
> +static struct aput_struct aput_cases[] = {
> +	{"x86_vendor",          aput_x86_vendor          },
> +	{"acpi_cpc_valid",      aput_acpi_cpc            },
> +	{"modprobed_driver",    aput_modprobed_driver    },
> +	{"capability_check",    aput_capability_check    },
> +	{"enable",              aput_enable              },
> +	{"init_perf",           aput_init_perf           },
> +	{"support_boost",       aput_support_boost       }
> +};
> +
> +static bool get_shared_mem(void)
> +{
> +	bool result = false;
> +	char buf[5] = {0};
> +	struct file *filp = NULL;
> +	loff_t pos = 0;
> +	ssize_t ret;
> +
> +	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_x86_vendor(u32 index)
> +{
> +	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
> +	{
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		aput_cases[index].result = APUT_RESULT_FAIL;
> +	}
> +}

Is this test needed?

the amd-pstate is only supported on AMD systems. If anything this should
be one of the first tests and have the testing bail out if this fails.

Or, have the script (amd_pstate_testmod.sh) verify this is an AMD system
before launching the tests.
 
> +
> +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_modprobed_driver(u32 index)
> +{
> +	if (cpufreq_get_current_driver())
> +	{
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		aput_cases[index].result = APUT_RESULT_FAIL;
> +	}
> +}

What is this testing?

Shouldn't you verify that the current driver is the amd-pstate driver? This
just verifies that there is a driver.

> +
> +static void aput_capability_check(u32 index)
> +{
> +	if (boot_cpu_has(X86_FEATURE_CPPC))
> +	{
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		//shared memory
> +		if (get_shared_mem())
> +		{
> +			aput_cases[index].result = APUT_RESULT_PASS;
> +		}
> +		else
> +		{
> +			aput_cases[index].result = APUT_RESULT_FAIL;
> +		}
> +	}
> +}

Another where I'm not sure what you're trying to test. If we're using amd-pstate
you have to be using either MSRs or shared memory. Either of these set the result
to PASS.

There are other test cases below that I have questions about but before digging into
them I think some additional documentation about what you're trying to test with this
module would be nice to have. Theses test seem more like verifying the amd-pstate
module is in use rather than testing anything.

-Nathan

> +
> +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;
> +	}
> +}
> +
> +static void aput_enable(u32 index)
> +{
> +	if (get_shared_mem())
> +	{
> +		//not check
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		aput_pstate_enable(index);
> +	}
> +}
> +
> +static void aput_init_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;
> +
> +	//get perf
> +	highest_perf = amd_get_highest_perf();
> +
> +	for_each_possible_cpu(cpu)
> +	{
> +		//get amd cpudata
> +		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 rdmsrl_safe_on_cpu MSR_AMD_CPPC_CAP1 ret=%d is error! \n", __func__, ret);
> +				return;
> +			}
> +
> +			//get perf from MSR
> +			nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1);
> +			lowest_nonlinear_perf = AMD_CPPC_LOWNONLIN_PERF(cap1);
> +			lowest_perf = AMD_CPPC_LOWEST_PERF(cap1);
> +		}
> +
> +		//check highest_perf,nominal_perf,lowest_nonlinear_perf
> +		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_perf=%d %d nominal_perf=%d %d lowest_nonlinear_perf=%d %d lowest_perf=%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;
> +		}
> +	}
> +
> +	aput_cases[index].result = APUT_RESULT_PASS;
> +}
> +
> +static void aput_support_boost(u32 index)
> +{
> +	int cpu = 0;
> +	struct cpufreq_policy *policy = NULL;
> +        struct amd_cpudata *cpudata = NULL;
> +
> +	for_each_possible_cpu(cpu)
> +	{
> +		//get amd cpudata
> +		policy = cpufreq_cpu_get(cpu);
> +		if (!policy)
> +			break;
> +		cpudata = policy->driver_data;
> +
> +		if (READ_ONCE(cpudata->boost_supported))
> +		{
> +			aput_cases[index].result = APUT_RESULT_PASS;
> +		}
> +		else
> +		{
> +			aput_cases[index].result = APUT_RESULT_FAIL;
> +			break;
> +		}
> +	}
> +}
> +
> +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_testmod);
> +MODULE_AUTHOR("Meng Li <li.meng@amd.com>");
> +MODULE_DESCRIPTION("Unit test for AMD P-state driver");
> +MODULE_LICENSE("GPL");

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 0/3] Add unit test module for AMD P-State driver
  2022-04-13 15:41 ` [PATCH v2 0/3] Add unit test module for AMD P-State driver Rafael J. Wysocki
@ 2022-04-17  1:38   ` Huang Rui
  0 siblings, 0 replies; 10+ messages in thread
From: Huang Rui @ 2022-04-17  1:38 UTC (permalink / raw)
  To: Rafael J. Wysocki, Meng, Li (Jassmine)
  Cc: Shuah Khan, Rafael J . Wysocki, Linux PM, Fontenot, Nathan,
	Sharma, Deepak, Deucher, Alexander, Limonciello, Mario, Su,
	Jinzhou (Joe),
	Yuan, Perry, Du, Xiaojian, Viresh Kumar, Borislav Petkov,
	Linux Kernel Mailing List

On Wed, Apr 13, 2022 at 11:41:44PM +0800, Rafael J. Wysocki wrote:
> On Wed, Apr 13, 2022 at 11:06 AM Meng Li <li.meng@amd.com> wrote:
> >
> > Hi all:
> >
> > AMD P-State unit test(amd_pstate_testmod) is a kernel module for testing
> > the functions of amd-pstate driver.
> > It could import as a module to launch some test tasks.
> >
> > 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_testmod module and tie it into kselftest.
> >
> > For exmaple: 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, its test cases are very simple, and the corresponding test
> > cases will continue to be added later to improve the test coverage.
> >
> > See patch series in below git repo:
> > V1: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Flinux-pm%2F20220323071502.2674156-1-li.meng%40amd.com%2F&amp;data=04%7C01%7Cray.huang%40amd.com%7C7a5d4998e2ca413a215b08da1d6425e4%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637854613222577975%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=8fAzN5hea4sVO5E7%2B9Uh9VSsyt29gM2%2FCkMXHS0%2FfP4%3D&amp;reserved=0
> >
> > 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.
> >
> > Thanks,
> > Jasmine
> >
> > Meng Li (3):
> >   cpufreq: amd-pstate: Expose struct amd_cpudata
> 
> Please collect an ACK from Ray for this one as per MAINTAINERS and I
> will leave the series to Shuah as it is selftests mostly.
> 
> Thanks!
> 

Thanks, Rafael!

Jassmine, I think you can mark all patches as "v2" not only the cover
letter. Then we can separate these series easily.

Thanks,
Ray

> >   selftests: cpufreq: Add wapper script for test AMD P-State
> >   selftests: cpufreq: Add amd_pstate_testmod kernel module for testing
> >
> >  MAINTAINERS                                   |   1 +
> >  drivers/cpufreq/amd-pstate.c                  |  60 +---
> >  include/linux/amd-pstate.h                    |  74 +++++
> >  tools/testing/selftests/cpufreq/Makefile      |   2 +-
> >  .../selftests/cpufreq/amd_pstate_testmod.sh   |   4 +
> >  .../cpufreq/amd_pstate_testmod/Makefile       |  20 ++
> >  .../amd_pstate_testmod/amd_pstate_testmod.c   | 302 ++++++++++++++++++
> >  tools/testing/selftests/cpufreq/config        |   1 +
> >  8 files changed, 404 insertions(+), 60 deletions(-)
> >  create mode 100644 include/linux/amd-pstate.h
> >  create mode 100755 tools/testing/selftests/cpufreq/amd_pstate_testmod.sh
> >  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
> >  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
> >
> > --
> > 2.25.1
> >

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] cpufreq: amd-pstate: Expose struct amd_cpudata
  2022-04-13  9:05 ` [PATCH 1/3] cpufreq: amd-pstate: Expose struct amd_cpudata Meng Li
@ 2022-04-17  2:09   ` Huang Rui
  0 siblings, 0 replies; 10+ messages in thread
From: Huang Rui @ 2022-04-17  2:09 UTC (permalink / raw)
  To: Meng Li
  Cc: Shuah Khan, Rafael J . Wysocki, linux-pm, Nathan Fontenot,
	Deepak Sharma, Alex Deucher, Mario Limonciello, Jinzhou Su,
	Perry Yuan, Xiaojian Du, Viresh Kumar, Borislav Petkov,
	linux-kernel

On Wed, Apr 13, 2022 at 05:05:08PM +0800, Meng Li wrote:
> Expose struct amd_cpudata to AMD P-State unit test module.
> 
> This data struct will be used on the following AMD P-State unit test
> (amd-pstate-ut) module. The amd-pstate-ut module can get some AMD
> infomations by this data struct. For example: highest perf,
> nominal perf, boost supported etc.
> 
> Signed-off-by: Meng Li <li.meng@amd.com>

Acked-by: Huang Rui <ray.huang@amd.com>

> ---
>  MAINTAINERS                  |  1 +
>  drivers/cpufreq/amd-pstate.c | 60 +----------------------------
>  include/linux/amd-pstate.h   | 74 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 76 insertions(+), 59 deletions(-)
>  create mode 100644 include/linux/amd-pstate.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9832b607e2e2..f108e83ba851 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1003,6 +1003,7 @@ S:	Supported
>  F:	Documentation/admin-guide/pm/amd-pstate.rst
>  F:	drivers/cpufreq/amd-pstate*
>  F:	tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
> +F:	include/linux/amd-pstate.h
>  
>  AMD PTDMA DRIVER
>  M:	Sanjay R Mehta <sanju.mehta@amd.com>
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index 7be38bc6a673..5f7a00a64f76 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -36,6 +36,7 @@
>  #include <linux/delay.h>
>  #include <linux/uaccess.h>
>  #include <linux/static_call.h>
> +#include <linux/amd-pstate.h>
>  
>  #include <acpi/processor.h>
>  #include <acpi/cppc_acpi.h>
> @@ -65,65 +66,6 @@ MODULE_PARM_DESC(shared_mem,
>  
>  static struct cpufreq_driver amd_pstate_driver;
>  
> -/**
> - * struct  amd_aperf_mperf
> - * @aperf: actual performance frequency clock count
> - * @mperf: maximum performance frequency clock count
> - * @tsc:   time stamp counter
> - */
> -struct amd_aperf_mperf {
> -	u64 aperf;
> -	u64 mperf;
> -	u64 tsc;
> -};
> -
> -/**
> - * struct amd_cpudata - private CPU data for AMD P-State
> - * @cpu: CPU number
> - * @req: constraint request to apply
> - * @cppc_req_cached: cached performance request hints
> - * @highest_perf: the maximum performance an individual processor may reach,
> - *		  assuming ideal conditions
> - * @nominal_perf: the maximum sustained performance level of the processor,
> - *		  assuming ideal operating conditions
> - * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power
> - *			   savings are achieved
> - * @lowest_perf: the absolute lowest performance level of the processor
> - * @max_freq: the frequency that mapped to highest_perf
> - * @min_freq: the frequency that mapped to lowest_perf
> - * @nominal_freq: the frequency that mapped to nominal_perf
> - * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
> - * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
> - * @prev: Last Aperf/Mperf/tsc count value read from register
> - * @freq: current cpu frequency value
> - * @boost_supported: check whether the Processor or SBIOS supports boost mode
> - *
> - * The amd_cpudata is key private data for each CPU thread in AMD P-State, and
> - * represents all the attributes and goals that AMD P-State requests at runtime.
> - */
> -struct amd_cpudata {
> -	int	cpu;
> -
> -	struct	freq_qos_request req[2];
> -	u64	cppc_req_cached;
> -
> -	u32	highest_perf;
> -	u32	nominal_perf;
> -	u32	lowest_nonlinear_perf;
> -	u32	lowest_perf;
> -
> -	u32	max_freq;
> -	u32	min_freq;
> -	u32	nominal_freq;
> -	u32	lowest_nonlinear_freq;
> -
> -	struct amd_aperf_mperf cur;
> -	struct amd_aperf_mperf prev;
> -
> -	u64 freq;
> -	bool	boost_supported;
> -};
> -
>  static inline int pstate_enable(bool enable)
>  {
>  	return wrmsrl_safe(MSR_AMD_CPPC_ENABLE, enable);
> diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h
> new file mode 100644
> index 000000000000..790b04c9000b
> --- /dev/null
> +++ b/include/linux/amd-pstate.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * linux/include/linux/amd-pstate.h
> + *
> + * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
> + * Author: Meng Li <li.meng@amd.com>
> + */
> +#ifndef _LINUX_AMD_PSTATE_H
> +#define _LINUX_AMD_PSTATE_H
> +
> +#include <linux/pm_qos.h>
> +/*********************************************************************
> + *                        AMD P-state INTERFACE                       *
> + *********************************************************************/
> +/**
> + * struct  amd_aperf_mperf
> + * @aperf: actual performance frequency clock count
> + * @mperf: maximum performance frequency clock count
> + * @tsc:   time stamp counter
> + */
> +struct amd_aperf_mperf {
> +	u64 aperf;
> +	u64 mperf;
> +	u64 tsc;
> +};
> +
> +/**
> + * struct amd_cpudata - private CPU data for AMD P-State
> + * @cpu: CPU number
> + * @req: constraint request to apply
> + * @cppc_req_cached: cached performance request hints
> + * @highest_perf: the maximum performance an individual processor may reach,
> + *		  assuming ideal conditions
> + * @nominal_perf: the maximum sustained performance level of the processor,
> + *		  assuming ideal operating conditions
> + * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power
> + *			   savings are achieved
> + * @lowest_perf: the absolute lowest performance level of the processor
> + * @max_freq: the frequency that mapped to highest_perf
> + * @min_freq: the frequency that mapped to lowest_perf
> + * @nominal_freq: the frequency that mapped to nominal_perf
> + * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
> + * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
> + * @prev: Last Aperf/Mperf/tsc count value read from register
> + * @freq: current cpu frequency value
> + * @boost_supported: check whether the Processor or SBIOS supports boost mode
> + *
> + * The amd_cpudata is key private data for each CPU thread in AMD P-State, and
> + * represents all the attributes and goals that AMD P-State requests at runtime.
> + */
> +struct amd_cpudata {
> +	int	cpu;
> +
> +	struct	freq_qos_request req[2];
> +	u64	cppc_req_cached;
> +
> +	u32	highest_perf;
> +	u32	nominal_perf;
> +	u32	lowest_nonlinear_perf;
> +	u32	lowest_perf;
> +
> +	u32	max_freq;
> +	u32	min_freq;
> +	u32	nominal_freq;
> +	u32	lowest_nonlinear_freq;
> +
> +	struct amd_aperf_mperf cur;
> +	struct amd_aperf_mperf prev;
> +
> +	u64	freq;
> +	bool	boost_supported;
> +};
> +
> +#endif /* _LINUX_AMD_PSTATE_H */
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing
  2022-04-13  9:05 ` [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing Meng Li
  2022-04-13 20:16   ` Nathan Fontenot
@ 2022-04-17 14:54   ` Huang Rui
  1 sibling, 0 replies; 10+ messages in thread
From: Huang Rui @ 2022-04-17 14:54 UTC (permalink / raw)
  To: Meng, Li (Jassmine)
  Cc: Shuah Khan, Rafael J . Wysocki, linux-pm, Fontenot, Nathan,
	Sharma, Deepak, Deucher, Alexander, Limonciello, Mario, Su,
	Jinzhou (Joe),
	Yuan, Perry, Du, Xiaojian, Viresh Kumar, Borislav Petkov,
	linux-kernel

On Wed, Apr 13, 2022 at 05:05:10PM +0800, Meng, Li (Jassmine) wrote:
> Add amd_pstate_testmod module, which is conceptually out-of-tree module and
> provides ways for selftests/cpufreq 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 <li.meng@amd.com>
> ---
>  .../cpufreq/amd_pstate_testmod/Makefile       |  20 ++
>  .../amd_pstate_testmod/amd_pstate_testmod.c   | 302 ++++++++++++++++++
>  2 files changed, 322 insertions(+)
>  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
>  create mode 100644 tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
> 
> diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile b/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
> new file mode 100644
> index 000000000000..8a5596cb2c18
> --- /dev/null
> +++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod/Makefile
> @@ -0,0 +1,20 @@
> +AMD_PSTATE_TESTMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
> +KDIR ?= $(abspath $(AMD_PSATE_TESTMOD_DIR)/../../../../..)
> +
> +ifeq ($(V),1)
> +Q =
> +else
> +Q = @
> +endif
> +
> +MODULES = amd_pstate_testmod.ko
> +
> +obj-m += amd_pstate_testmod.o
> +CFLAGS_amd_pstate_testmod.o = -I$(src)
> +
> +all:
> +	+$(Q)make -C $(KDIR) M=$(AMD_PSTATE_TESTMOD_DIR) modules
> +
> +clean:
> +	+$(Q)make -C $(KDIR) M=$(AMD_PSTATE_TESTMOD_DIR) clean
> +
> diff --git a/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c b/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
> new file mode 100644
> index 000000000000..a892cecf19da
> --- /dev/null
> +++ b/tools/testing/selftests/cpufreq/amd_pstate_testmod/amd_pstate_testmod.c
> @@ -0,0 +1,302 @@
> +// 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 <li.meng@amd.com>
> + *

We would like to explain the goal or intention of the AMD P-State Unit Test
module here.

E.X.:

1. The AMD P-State Unit Test 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 udpate.
3. We can introduce more functional or performance tests to align the
result together, it will benifit power and performance scale optimization.

> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include "../../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,	//0

Let's remove "//" in the comments at whole series.

https://www.kernel.org/doc/html/latest/process/coding-style.html#commenting

> +	APUT_RESULT_FAIL,	//
> +	MAX_APUT_RESULT,
> +};
> +
> +struct aput_struct {
> +	const char *name;
> +	void (*func)(u32 index);
> +	enum aput_result result;
> +};
> +
> +static void aput_x86_vendor(u32 index);
> +static void aput_acpi_cpc(u32 index);
> +static void aput_modprobed_driver(u32 index);
> +static void aput_capability_check(u32 index);
> +static void aput_enable(u32 index);
> +static void aput_init_perf(u32 index);
> +static void aput_support_boost(u32 index);
> +
> +static struct aput_struct aput_cases[] = {
> +	{"x86_vendor",          aput_x86_vendor          },
> +	{"acpi_cpc_valid",      aput_acpi_cpc            },
> +	{"modprobed_driver",    aput_modprobed_driver    },
> +	{"capability_check",    aput_capability_check    },
> +	{"enable",              aput_enable              },
> +	{"init_perf",           aput_init_perf           },
> +	{"support_boost",       aput_support_boost       }
> +};
> +
> +static bool get_shared_mem(void)
> +{
> +	bool result = false;
> +	char buf[5] = {0};
> +	struct file *filp = NULL;
> +	loff_t pos = 0;
> +	ssize_t ret;
> +
> +	filp = filp_open("/sys/module/amd_pstate/parameters/shared_mem", FMODE_PREAD, 0);
> +	if (IS_ERR(filp))
> +	{

We need use

if () {
}

instead of

if ()
{
}

Please use the checkpatch.pl to check your patches.

> +		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_x86_vendor(u32 index)
> +{
> +	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
> +	{
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		aput_cases[index].result = APUT_RESULT_FAIL;
> +	}
> +}
> +
> +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_modprobed_driver(u32 index)
> +{
> +	if (cpufreq_get_current_driver())
> +	{
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		aput_cases[index].result = APUT_RESULT_FAIL;
> +	}
> +}
> +
> +static void aput_capability_check(u32 index)
> +{
> +	if (boot_cpu_has(X86_FEATURE_CPPC))
> +	{
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		//shared memory
> +		if (get_shared_mem())
> +		{
> +			aput_cases[index].result = APUT_RESULT_PASS;
> +		}
> +		else
> +		{
> +			aput_cases[index].result = APUT_RESULT_FAIL;
> +		}

I am thinking if the share_mem is not 1, system will fall back to
acpi-cpufreq. And won't modprobe the amd-pstate module. Is this duplicate
with above modprobed test?

> +	}
> +}
> +
> +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;
> +	}
> +}
> +
> +static void aput_enable(u32 index)
> +{
> +	if (get_shared_mem())
> +	{
> +		//not check
> +		aput_cases[index].result = APUT_RESULT_PASS;
> +	}
> +	else
> +	{
> +		aput_pstate_enable(index);
> +	}
> +}
> +
> +static void aput_init_perf(u32 index)

For this test, we should check if the each performance values are
reasonable.

E.X:

highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0

Do we need a similar checking for the CPU frequencies?

> +{
> +	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;
> +
> +	//get perf
> +	highest_perf = amd_get_highest_perf();
> +
> +	for_each_possible_cpu(cpu)
> +	{
> +		//get amd cpudata
> +		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 rdmsrl_safe_on_cpu MSR_AMD_CPPC_CAP1 ret=%d is error! \n", __func__, ret);
> +				return;
> +			}
> +
> +			//get perf from MSR
> +			nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1);
> +			lowest_nonlinear_perf = AMD_CPPC_LOWNONLIN_PERF(cap1);
> +			lowest_perf = AMD_CPPC_LOWEST_PERF(cap1);
> +		}
> +
> +		//check highest_perf,nominal_perf,lowest_nonlinear_perf
> +		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_perf=%d %d nominal_perf=%d %d lowest_nonlinear_perf=%d %d lowest_perf=%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;
> +		}
> +	}
> +
> +	aput_cases[index].result = APUT_RESULT_PASS;
> +}
> +
> +static void aput_support_boost(u32 index)
> +{
> +	int cpu = 0;
> +	struct cpufreq_policy *policy = NULL;
> +        struct amd_cpudata *cpudata = NULL;

Please align the space in this line.

Thanks,
Ray

> +
> +	for_each_possible_cpu(cpu)
> +	{
> +		//get amd cpudata
> +		policy = cpufreq_cpu_get(cpu);
> +		if (!policy)
> +			break;
> +		cpudata = policy->driver_data;
> +
> +		if (READ_ONCE(cpudata->boost_supported))
> +		{
> +			aput_cases[index].result = APUT_RESULT_PASS;
> +		}
> +		else
> +		{
> +			aput_cases[index].result = APUT_RESULT_FAIL;
> +			break;
> +		}
> +	}
> +}
> +
> +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_testmod);
> +MODULE_AUTHOR("Meng Li <li.meng@amd.com>");
> +MODULE_DESCRIPTION("Unit test for AMD P-state driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-04-17 14:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-13  9:05 [PATCH v2 0/3] Add unit test module for AMD P-State driver Meng Li
2022-04-13  9:05 ` [PATCH 1/3] cpufreq: amd-pstate: Expose struct amd_cpudata Meng Li
2022-04-17  2:09   ` Huang Rui
2022-04-13  9:05 ` [PATCH 2/3] selftests: cpufreq: Add wapper script for test AMD P-State Meng Li
2022-04-13 19:55   ` Nathan Fontenot
2022-04-13  9:05 ` [PATCH 3/3] selftests: cpufreq: Add amd_pstate_testmod kernel module for testing Meng Li
2022-04-13 20:16   ` Nathan Fontenot
2022-04-17 14:54   ` Huang Rui
2022-04-13 15:41 ` [PATCH v2 0/3] Add unit test module for AMD P-State driver Rafael J. Wysocki
2022-04-17  1:38   ` Huang Rui

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).