[v2,3/4] cpufreq: amd-pstate: Add a kernel config option to set default mode
Commit Message
From: Mario Limonciello <mario.limonciello@amd.com>
Users are having more success with amd-pstate since the introduction
of EPP and Guided modes. To expose the driver to more users by default
introduce a kernel configuration option for setting the default mode.
Users can use an integer to map out which default mode they want to use
in lieu of a kernel command line option.
This will default to EPP, but only if:
1) The CPU supports an MSR.
2) The system profile is identified
3) The system profile is identified as a non-server by the FADT.
Link: https://gitlab.freedesktop.org/hadess/power-profiles-daemon/-/merge_requests/121
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
Co-developed-by: Perry Yuan <perry.yuan@amd.com>
Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
drivers/cpufreq/Kconfig.x86 | 17 +++++++++
drivers/cpufreq/amd-pstate.c | 73 ++++++++++++++++++++++++------------
include/linux/amd-pstate.h | 4 +-
3 files changed, 68 insertions(+), 26 deletions(-)
Comments
On Thu, Jun 15, 2023 at 02:33:00PM +0800, Yuan, Perry wrote:
> From: Mario Limonciello <mario.limonciello@amd.com>
>
> Users are having more success with amd-pstate since the introduction
> of EPP and Guided modes. To expose the driver to more users by default
> introduce a kernel configuration option for setting the default mode.
>
> Users can use an integer to map out which default mode they want to use
> in lieu of a kernel command line option.
>
> This will default to EPP, but only if:
> 1) The CPU supports an MSR.
> 2) The system profile is identified
> 3) The system profile is identified as a non-server by the FADT.
>
> Link: https://gitlab.freedesktop.org/hadess/power-profiles-daemon/-/merge_requests/121
> Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
> Co-developed-by: Perry Yuan <perry.yuan@amd.com>
> Signed-off-by: Perry Yuan <perry.yuan@amd.com>
> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Acked-by: Huang Rui <ray.huang@amd.com>
> ---
> drivers/cpufreq/Kconfig.x86 | 17 +++++++++
> drivers/cpufreq/amd-pstate.c | 73 ++++++++++++++++++++++++------------
> include/linux/amd-pstate.h | 4 +-
> 3 files changed, 68 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
> index 00476e94db90..438c9e75a04d 100644
> --- a/drivers/cpufreq/Kconfig.x86
> +++ b/drivers/cpufreq/Kconfig.x86
> @@ -51,6 +51,23 @@ config X86_AMD_PSTATE
>
> If in doubt, say N.
>
> +config X86_AMD_PSTATE_DEFAULT_MODE
> + int "AMD Processor P-State default mode"
> + depends on X86_AMD_PSTATE
> + default 3 if X86_AMD_PSTATE
> + range 1 4
> + help
> + Select the default mode the amd-pstate driver will use on
> + supported hardware.
> + The value set has the following meanings:
> + 1 -> Disabled
> + 2 -> Passive
> + 3 -> Active (EPP)
> + 4 -> Guided
> +
> + For details, take a look at:
> + <file:Documentation/admin-guide/pm/amd-pstate.rst>.
> +
> config X86_AMD_PSTATE_UT
> tristate "selftest for AMD Processor P-State driver"
> depends on X86 && ACPI_PROCESSOR
> diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
> index c9d296ebf81e..b400d1ee8e64 100644
> --- a/drivers/cpufreq/amd-pstate.c
> +++ b/drivers/cpufreq/amd-pstate.c
> @@ -62,7 +62,7 @@
> static struct cpufreq_driver *current_pstate_driver;
> static struct cpufreq_driver amd_pstate_driver;
> static struct cpufreq_driver amd_pstate_epp_driver;
> -static int cppc_state = AMD_PSTATE_DISABLE;
> +static int cppc_state = AMD_PSTATE_UNDEFINED;
>
> /*
> * AMD Energy Preference Performance (EPP)
> @@ -1363,6 +1363,25 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
> .attr = amd_pstate_epp_attr,
> };
>
> +static int __init amd_pstate_set_driver(int mode_idx)
> +{
> + if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
> + cppc_state = mode_idx;
> + if (cppc_state == AMD_PSTATE_DISABLE)
> + pr_info("driver is explicitly disabled\n");
> +
> + if (cppc_state == AMD_PSTATE_ACTIVE)
> + current_pstate_driver = &amd_pstate_epp_driver;
> +
> + if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
> + current_pstate_driver = &amd_pstate_driver;
> +
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> static int __init amd_pstate_init(void)
> {
> struct device *dev_root;
> @@ -1370,15 +1389,6 @@ static int __init amd_pstate_init(void)
>
> if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
> return -ENODEV;
> - /*
> - * by default the pstate driver is disabled to load
> - * enable the amd_pstate passive mode driver explicitly
> - * with amd_pstate=passive or other modes in kernel command line
> - */
> - if (cppc_state == AMD_PSTATE_DISABLE) {
> - pr_info("driver load is disabled, boot with specific mode to enable this\n");
> - return -ENODEV;
> - }
>
> if (!acpi_cpc_valid()) {
> pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n");
> @@ -1389,6 +1399,33 @@ static int __init amd_pstate_init(void)
> if (cpufreq_get_current_driver())
> return -EEXIST;
>
> + switch (cppc_state) {
> + case AMD_PSTATE_UNDEFINED:
> + /* Disable on the following configs by default:
> + * 1. Undefined platforms
> + * 2. Server platforms
> + * 3. Shared memory designs
> + */
> + if (acpi_pm_profile_undefined() ||
> + acpi_pm_profile_server() ||
> + !boot_cpu_has(X86_FEATURE_CPPC)) {
> + pr_info("driver load is disabled, boot with specific mode to enable this\n");
> + return -ENODEV;
> + }
> + ret = amd_pstate_set_driver(CONFIG_X86_AMD_PSTATE_DEFAULT_MODE);
> + if (ret)
> + return ret;
> + break;
> + case AMD_PSTATE_DISABLE:
> + return -ENODEV;
> + case AMD_PSTATE_PASSIVE:
> + case AMD_PSTATE_ACTIVE:
> + case AMD_PSTATE_GUIDED:
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> /* capability check */
> if (boot_cpu_has(X86_FEATURE_CPPC)) {
> pr_debug("AMD CPPC MSR based functionality is supported\n");
> @@ -1441,21 +1478,7 @@ static int __init amd_pstate_param(char *str)
> size = strlen(str);
> mode_idx = get_mode_idx_from_str(str, size);
>
> - if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
> - cppc_state = mode_idx;
> - if (cppc_state == AMD_PSTATE_DISABLE)
> - pr_info("driver is explicitly disabled\n");
> -
> - if (cppc_state == AMD_PSTATE_ACTIVE)
> - current_pstate_driver = &amd_pstate_epp_driver;
> -
> - if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
> - current_pstate_driver = &amd_pstate_driver;
> -
> - return 0;
> - }
> -
> - return -EINVAL;
> + return amd_pstate_set_driver(mode_idx);
> }
> early_param("amd_pstate", amd_pstate_param);
>
> diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h
> index c10ebf8c42e6..446394f84606 100644
> --- a/include/linux/amd-pstate.h
> +++ b/include/linux/amd-pstate.h
> @@ -94,7 +94,8 @@ struct amd_cpudata {
> * enum amd_pstate_mode - driver working mode of amd pstate
> */
> enum amd_pstate_mode {
> - AMD_PSTATE_DISABLE = 0,
> + AMD_PSTATE_UNDEFINED = 0,
> + AMD_PSTATE_DISABLE,
> AMD_PSTATE_PASSIVE,
> AMD_PSTATE_ACTIVE,
> AMD_PSTATE_GUIDED,
> @@ -102,6 +103,7 @@ enum amd_pstate_mode {
> };
>
> static const char * const amd_pstate_mode_string[] = {
> + [AMD_PSTATE_UNDEFINED] = "undefined",
> [AMD_PSTATE_DISABLE] = "disable",
> [AMD_PSTATE_PASSIVE] = "passive",
> [AMD_PSTATE_ACTIVE] = "active",
> --
> 2.34.1
>
@@ -51,6 +51,23 @@ config X86_AMD_PSTATE
If in doubt, say N.
+config X86_AMD_PSTATE_DEFAULT_MODE
+ int "AMD Processor P-State default mode"
+ depends on X86_AMD_PSTATE
+ default 3 if X86_AMD_PSTATE
+ range 1 4
+ help
+ Select the default mode the amd-pstate driver will use on
+ supported hardware.
+ The value set has the following meanings:
+ 1 -> Disabled
+ 2 -> Passive
+ 3 -> Active (EPP)
+ 4 -> Guided
+
+ For details, take a look at:
+ <file:Documentation/admin-guide/pm/amd-pstate.rst>.
+
config X86_AMD_PSTATE_UT
tristate "selftest for AMD Processor P-State driver"
depends on X86 && ACPI_PROCESSOR
@@ -62,7 +62,7 @@
static struct cpufreq_driver *current_pstate_driver;
static struct cpufreq_driver amd_pstate_driver;
static struct cpufreq_driver amd_pstate_epp_driver;
-static int cppc_state = AMD_PSTATE_DISABLE;
+static int cppc_state = AMD_PSTATE_UNDEFINED;
/*
* AMD Energy Preference Performance (EPP)
@@ -1363,6 +1363,25 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
.attr = amd_pstate_epp_attr,
};
+static int __init amd_pstate_set_driver(int mode_idx)
+{
+ if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
+ cppc_state = mode_idx;
+ if (cppc_state == AMD_PSTATE_DISABLE)
+ pr_info("driver is explicitly disabled\n");
+
+ if (cppc_state == AMD_PSTATE_ACTIVE)
+ current_pstate_driver = &amd_pstate_epp_driver;
+
+ if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
+ current_pstate_driver = &amd_pstate_driver;
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static int __init amd_pstate_init(void)
{
struct device *dev_root;
@@ -1370,15 +1389,6 @@ static int __init amd_pstate_init(void)
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return -ENODEV;
- /*
- * by default the pstate driver is disabled to load
- * enable the amd_pstate passive mode driver explicitly
- * with amd_pstate=passive or other modes in kernel command line
- */
- if (cppc_state == AMD_PSTATE_DISABLE) {
- pr_info("driver load is disabled, boot with specific mode to enable this\n");
- return -ENODEV;
- }
if (!acpi_cpc_valid()) {
pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n");
@@ -1389,6 +1399,33 @@ static int __init amd_pstate_init(void)
if (cpufreq_get_current_driver())
return -EEXIST;
+ switch (cppc_state) {
+ case AMD_PSTATE_UNDEFINED:
+ /* Disable on the following configs by default:
+ * 1. Undefined platforms
+ * 2. Server platforms
+ * 3. Shared memory designs
+ */
+ if (acpi_pm_profile_undefined() ||
+ acpi_pm_profile_server() ||
+ !boot_cpu_has(X86_FEATURE_CPPC)) {
+ pr_info("driver load is disabled, boot with specific mode to enable this\n");
+ return -ENODEV;
+ }
+ ret = amd_pstate_set_driver(CONFIG_X86_AMD_PSTATE_DEFAULT_MODE);
+ if (ret)
+ return ret;
+ break;
+ case AMD_PSTATE_DISABLE:
+ return -ENODEV;
+ case AMD_PSTATE_PASSIVE:
+ case AMD_PSTATE_ACTIVE:
+ case AMD_PSTATE_GUIDED:
+ break;
+ default:
+ return -EINVAL;
+ }
+
/* capability check */
if (boot_cpu_has(X86_FEATURE_CPPC)) {
pr_debug("AMD CPPC MSR based functionality is supported\n");
@@ -1441,21 +1478,7 @@ static int __init amd_pstate_param(char *str)
size = strlen(str);
mode_idx = get_mode_idx_from_str(str, size);
- if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
- cppc_state = mode_idx;
- if (cppc_state == AMD_PSTATE_DISABLE)
- pr_info("driver is explicitly disabled\n");
-
- if (cppc_state == AMD_PSTATE_ACTIVE)
- current_pstate_driver = &amd_pstate_epp_driver;
-
- if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
- current_pstate_driver = &amd_pstate_driver;
-
- return 0;
- }
-
- return -EINVAL;
+ return amd_pstate_set_driver(mode_idx);
}
early_param("amd_pstate", amd_pstate_param);
@@ -94,7 +94,8 @@ struct amd_cpudata {
* enum amd_pstate_mode - driver working mode of amd pstate
*/
enum amd_pstate_mode {
- AMD_PSTATE_DISABLE = 0,
+ AMD_PSTATE_UNDEFINED = 0,
+ AMD_PSTATE_DISABLE,
AMD_PSTATE_PASSIVE,
AMD_PSTATE_ACTIVE,
AMD_PSTATE_GUIDED,
@@ -102,6 +103,7 @@ enum amd_pstate_mode {
};
static const char * const amd_pstate_mode_string[] = {
+ [AMD_PSTATE_UNDEFINED] = "undefined",
[AMD_PSTATE_DISABLE] = "disable",
[AMD_PSTATE_PASSIVE] = "passive",
[AMD_PSTATE_ACTIVE] = "active",