|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 03/11] xen/x86: introduce "cpufreq=amd-pstate" xen cmdline
Users need to set "cpufreq=amd-pstate" in xen cmdline to enable
amd-pstate driver, which selects ACPI Collaborative Performance
and Power Control (CPPC) on supported AMD hardware to provide a
finer grained frequency control mechanism.
`verbose` option can also be included to support verbose print.
When users setting "cpufreq=amd-pstate", a new amd-pstate driver
shall be registered and used. Actual implmentation will be introduced
in the following commits.
Signed-off-by: Penny Zheng <Penny.Zheng@xxxxxxx>
---
docs/misc/xen-command-line.pandoc | 8 +++-
xen/arch/x86/acpi/cpufreq/Makefile | 1 +
xen/arch/x86/acpi/cpufreq/amd-pstate.c | 66 ++++++++++++++++++++++++++
xen/arch/x86/acpi/cpufreq/cpufreq.c | 28 +++++++++++
xen/arch/x86/platform_hypercall.c | 6 +++
xen/drivers/cpufreq/cpufreq.c | 13 ++++-
xen/include/acpi/cpufreq/cpufreq.h | 4 ++
xen/include/public/platform.h | 1 +
xen/include/public/sysctl.h | 1 +
9 files changed, 124 insertions(+), 4 deletions(-)
create mode 100644 xen/arch/x86/acpi/cpufreq/amd-pstate.c
diff --git a/docs/misc/xen-command-line.pandoc
b/docs/misc/xen-command-line.pandoc
index 293dbc1a95..30f855fa18 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -499,7 +499,7 @@ If set, force use of the performance counters for oprofile,
rather than detectin
available support.
### cpufreq
-> `= none | {{ <boolean> | xen } {
[:[powersave|performance|ondemand|userspace][,[<maxfreq>]][,[<minfreq>]]] }
[,verbose]} | dom0-kernel | hwp[:[<hdc>][,verbose]]`
+> `= none | {{ <boolean> | xen } {
[:[powersave|performance|ondemand|userspace][,[<maxfreq>]][,[<minfreq>]]] }
[,verbose]} | dom0-kernel | hwp[:[<hdc>][,verbose]] | amd-pstate[:[verbose]]`
> Default: `xen`
@@ -510,7 +510,7 @@ choice of `dom0-kernel` is deprecated and not supported by
all Dom0 kernels.
* `<maxfreq>` and `<minfreq>` are integers which represent max and min
processor frequencies
respectively.
* `verbose` option can be included as a string or also as `verbose=<integer>`
- for `xen`. It is a boolean for `hwp`.
+ for `xen`. It is a boolean for `hwp` and `amd-pstate`.
* `hwp` selects Hardware-Controlled Performance States (HWP) on supported Intel
hardware. HWP is a Skylake+ feature which provides better CPU power
management. The default is disabled. If `hwp` is selected, but hardware
@@ -518,6 +518,10 @@ choice of `dom0-kernel` is deprecated and not supported by
all Dom0 kernels.
* `<hdc>` is a boolean to enable Hardware Duty Cycling (HDC). HDC enables the
processor to autonomously force physical package components into idle state.
The default is enabled, but the option only applies when `hwp` is enabled.
+* `amd-pstate` selects ACPI Collaborative Performance and Power Control (CPPC)
+ on supported AMD hardware to provide a finer grained frequency control
mechanism.
+ The default is disabled. If `amd-pstate` is selected, but hardware support
+ is not available, Xen will fallback to cpufreq=xen.
There is also support for `;`-separated fallback options:
`cpufreq=hwp;xen,verbose`. This first tries `hwp` and falls back to `xen` if
diff --git a/xen/arch/x86/acpi/cpufreq/Makefile
b/xen/arch/x86/acpi/cpufreq/Makefile
index e7dbe434a8..1710fc776c 100644
--- a/xen/arch/x86/acpi/cpufreq/Makefile
+++ b/xen/arch/x86/acpi/cpufreq/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_INTEL) += acpi.o
obj-y += cpufreq.o
+obj-y += amd-pstate.o
obj-$(CONFIG_INTEL) += hwp.o
obj-$(CONFIG_AMD) += powernow.o
diff --git a/xen/arch/x86/acpi/cpufreq/amd-pstate.c
b/xen/arch/x86/acpi/cpufreq/amd-pstate.c
new file mode 100644
index 0000000000..bfad96ae3d
--- /dev/null
+++ b/xen/arch/x86/acpi/cpufreq/amd-pstate.c
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * amd-pstate.c - AMD Processor P-state Frequency Driver
+ *
+ * Copyright (C) 2024 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ * Author: Penny Zheng <penny.zheng@xxxxxxx>
+ *
+ * AMD P-State introduces a new CPU performance scaling design for AMD
+ * processors using the ACPI Collaborative Performance and Power Control (CPPC)
+ * feature which provides a finer grained frequency control range.
+ *
+ */
+
+#include <xen/init.h>
+#include <xen/param.h>
+#include <acpi/cpufreq/cpufreq.h>
+
+uint16_t __read_mostly dmi_max_speed_mhz;
+
+static bool __init amd_pstate_handle_option(const char *s, const char *end)
+{
+ int ret;
+
+ ret = parse_boolean("verbose", s, end);
+ if ( ret >= 0 )
+ {
+ cpufreq_verbose = ret;
+ return true;
+ }
+
+ return false;
+}
+
+int __init amd_pstate_cmdline_parse(const char *s, const char *e)
+{
+ do
+ {
+ const char *end = strpbrk(s, ",;");
+
+ if ( !amd_pstate_handle_option(s, end) )
+ {
+ printk(XENLOG_WARNING "cpufreq/amd-pstate: option '%.*s' not
recognized\n",
+ (int)((end ?: e) - s), s);
+
+ return -EINVAL;
+ }
+
+ s = end ? ++end : end;
+ } while ( s && s < e );
+
+ return 0;
+}
+
+static const struct cpufreq_driver __initconstrel amd_pstate_cpufreq_driver =
+{
+ .name = XEN_AMD_PSTATE_DRIVER_NAME,
+};
+
+int __init amd_pstate_register_driver(void)
+{
+ if ( !cpu_has_cppc )
+ return -ENODEV;
+
+ return cpufreq_register_driver(&amd_pstate_cpufreq_driver);
+}
diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c
b/xen/arch/x86/acpi/cpufreq/cpufreq.c
index 61e98b67bd..a461cfc7b3 100644
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c
@@ -148,6 +148,9 @@ static int __init cf_check cpufreq_driver_init(void)
case CPUFREQ_none:
ret = 0;
break;
+ default:
+ printk(XENLOG_WARNING "Unsupported cpufreq driver for
vendor Intel\n");
+ break;
}
if ( ret != -ENODEV )
@@ -156,6 +159,31 @@ static int __init cf_check cpufreq_driver_init(void)
break;
case X86_VENDOR_AMD:
+ ret = -ENOENT;
+
+ for ( unsigned int i = 0; i < cpufreq_xen_cnt; i++ )
+ {
+ switch ( cpufreq_xen_opts[i] )
+ {
+ case CPUFREQ_xen:
+ ret = powernow_register_driver();
+ break;
+ case CPUFREQ_amd_pstate:
+ ret = amd_pstate_register_driver();
+ break;
+ case CPUFREQ_none:
+ ret = 0;
+ break;
+ default:
+ printk(XENLOG_WARNING "Unsupported cpufreq driver for
vendor AMD\n");
+ break;
+ }
+
+ if ( ret != -ENODEV )
+ break;
+ }
+ break;
+
case X86_VENDOR_HYGON:
ret = IS_ENABLED(CONFIG_AMD) ? powernow_register_driver() :
-ENODEV;
break;
diff --git a/xen/arch/x86/platform_hypercall.c
b/xen/arch/x86/platform_hypercall.c
index 917c395f58..4720c30e7e 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -574,6 +574,12 @@ ret_t do_platform_op(
case XEN_PM_CPPC:
{
+ if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CPPC) )
+ {
+ ret = -ENOSYS;
+ break;
+ }
+
ret = set_cppc_pminfo(op->u.set_pminfo.id,
&op->u.set_pminfo.u.cppc_data);
}
break;
diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
index 3e3392da1b..54d554aa4f 100644
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -84,7 +84,7 @@ static int __init cf_check setup_cpufreq_option(const char
*str)
if ( choice < 0 && !cmdline_strcmp(str, "dom0-kernel") )
{
- xen_processor_pmbits &= ~XEN_PROCESSOR_PM_PX;
+ xen_processor_pmbits &= ~(XEN_PROCESSOR_PM_PX|XEN_PROCESSOR_PM_CPPC);
cpufreq_controller = FREQCTL_dom0_kernel;
opt_dom0_vcpus_pin = 1;
return 0;
@@ -92,7 +92,7 @@ static int __init cf_check setup_cpufreq_option(const char
*str)
if ( choice == 0 || !cmdline_strcmp(str, "none") )
{
- xen_processor_pmbits &= ~XEN_PROCESSOR_PM_PX;
+ xen_processor_pmbits &= ~(XEN_PROCESSOR_PM_PX|XEN_PROCESSOR_PM_CPPC);
cpufreq_controller = FREQCTL_none;
return 0;
}
@@ -130,6 +130,15 @@ static int __init cf_check setup_cpufreq_option(const char
*str)
if ( arg[0] && arg[1] )
ret = hwp_cmdline_parse(arg + 1, end);
}
+ else if ( choice < 0 && !cmdline_strcmp(str, "amd-pstate") )
+ {
+ xen_processor_pmbits |= XEN_PROCESSOR_PM_CPPC;
+ cpufreq_controller = FREQCTL_xen;
+ cpufreq_xen_opts[cpufreq_xen_cnt++] = CPUFREQ_amd_pstate;
+ ret = 0;
+ if ( arg[0] && arg[1] )
+ ret = amd_pstate_cmdline_parse(arg + 1, end);
+ }
else
ret = -EINVAL;
diff --git a/xen/include/acpi/cpufreq/cpufreq.h
b/xen/include/acpi/cpufreq/cpufreq.h
index 3f1b05a02e..71e8ca91f0 100644
--- a/xen/include/acpi/cpufreq/cpufreq.h
+++ b/xen/include/acpi/cpufreq/cpufreq.h
@@ -28,6 +28,7 @@ enum cpufreq_xen_opt {
CPUFREQ_none,
CPUFREQ_xen,
CPUFREQ_hwp,
+ CPUFREQ_amd_pstate,
};
extern enum cpufreq_xen_opt cpufreq_xen_opts[2];
extern unsigned int cpufreq_xen_cnt;
@@ -267,4 +268,7 @@ int set_hwp_para(struct cpufreq_policy *policy,
int acpi_cpufreq_register(void);
+int amd_pstate_cmdline_parse(const char *s, const char *e);
+int amd_pstate_register_driver(void);
+
#endif /* __XEN_CPUFREQ_PM_H__ */
diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h
index be1cf9a12f..ad942f1775 100644
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -357,6 +357,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
#define XEN_PROCESSOR_PM_CX 1
#define XEN_PROCESSOR_PM_PX 2
#define XEN_PROCESSOR_PM_TX 4
+#define XEN_PROCESSOR_PM_CPPC 8
/* cmd type */
#define XEN_PM_CX 0
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index b0fec271d3..df4f362681 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -424,6 +424,7 @@ struct xen_set_cppc_para {
};
#define XEN_HWP_DRIVER_NAME "hwp"
+#define XEN_AMD_PSTATE_DRIVER_NAME "amd-pstate"
/*
* cpufreq para name of this structure named
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |