|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v9 1/8] xen/cpufreq: embed hwp into struct cpufreq_policy{}
For cpus sharing one cpufreq domain, cpufreq_driver.init() is
only invoked on the firstcpu, so current per-CPU hwp driver data
struct hwp_drv_data{} actually fails to be allocated for cpus other than the
first one. There is no need to make it per-CPU.
We embed struct hwp_drv_data{} into struct cpufreq_policy{}, then cpus could
share the hwp driver data allocated for the firstcpu, like the way they share
struct cpufreq_policy{}. We also make it a union, with "hwp", and later
"amd-cppc" as a sub-struct.
Suggested-by: Jan Beulich <jbeulich@xxxxxxxx>
Signed-off-by: Penny Zheng <Penny.Zheng@xxxxxxx>
---
v8 -> v9:
- new commit
---
xen/arch/x86/acpi/cpufreq/hwp.c | 32 +++++++++++++-----------------
xen/include/acpi/cpufreq/cpufreq.h | 6 ++++++
2 files changed, 20 insertions(+), 18 deletions(-)
diff --git a/xen/arch/x86/acpi/cpufreq/hwp.c b/xen/arch/x86/acpi/cpufreq/hwp.c
index 240491c96a..5c98f3eb3e 100644
--- a/xen/arch/x86/acpi/cpufreq/hwp.c
+++ b/xen/arch/x86/acpi/cpufreq/hwp.c
@@ -67,7 +67,6 @@ struct hwp_drv_data
uint8_t desired;
uint8_t energy_perf;
};
-static DEFINE_PER_CPU_READ_MOSTLY(struct hwp_drv_data *, hwp_drv_data);
#define hwp_err(cpu, fmt, args...) \
printk(XENLOG_ERR "HWP: CPU%u error: " fmt, cpu, ## args)
@@ -224,7 +223,7 @@ static bool __init hwp_available(void)
static int cf_check hwp_cpufreq_verify(struct cpufreq_policy *policy)
{
- struct hwp_drv_data *data = per_cpu(hwp_drv_data, policy->cpu);
+ struct hwp_drv_data *data = policy->u.hwp;
if ( !feature_hwp_activity_window && data->activity_window )
{
@@ -239,7 +238,7 @@ static int cf_check hwp_cpufreq_verify(struct
cpufreq_policy *policy)
static void cf_check hwp_write_request(void *info)
{
const struct cpufreq_policy *policy = info;
- struct hwp_drv_data *data = this_cpu(hwp_drv_data);
+ struct hwp_drv_data *data = policy->u.hwp;
union hwp_request hwp_req = data->curr_req;
data->ret = 0;
@@ -259,7 +258,7 @@ static int cf_check hwp_cpufreq_target(struct
cpufreq_policy *policy,
unsigned int relation)
{
unsigned int cpu = policy->cpu;
- struct hwp_drv_data *data = per_cpu(hwp_drv_data, cpu);
+ struct hwp_drv_data *data = policy->u.hwp;
/* Zero everything to ensure reserved bits are zero... */
union hwp_request hwp_req = { .raw = 0 };
@@ -350,7 +349,7 @@ static void hwp_get_cpu_speeds(struct cpufreq_policy
*policy)
static void cf_check hwp_init_msrs(void *info)
{
struct cpufreq_policy *policy = info;
- struct hwp_drv_data *data = this_cpu(hwp_drv_data);
+ struct hwp_drv_data *data = policy->u.hwp;
uint64_t val;
/*
@@ -426,15 +425,14 @@ static int cf_check hwp_cpufreq_cpu_init(struct
cpufreq_policy *policy)
policy->governor = &cpufreq_gov_hwp;
- per_cpu(hwp_drv_data, cpu) = data;
+ policy->u.hwp = data;
on_selected_cpus(cpumask_of(cpu), hwp_init_msrs, policy, 1);
if ( data->curr_req.raw == -1 )
{
hwp_err(cpu, "Could not initialize HWP properly\n");
- per_cpu(hwp_drv_data, cpu) = NULL;
- xfree(data);
+ XFREE(policy->u.hwp);
return -ENODEV;
}
@@ -462,10 +460,8 @@ static int cf_check hwp_cpufreq_cpu_init(struct
cpufreq_policy *policy)
static int cf_check hwp_cpufreq_cpu_exit(struct cpufreq_policy *policy)
{
- struct hwp_drv_data *data = per_cpu(hwp_drv_data, policy->cpu);
-
- per_cpu(hwp_drv_data, policy->cpu) = NULL;
- xfree(data);
+ if ( policy->u.hwp )
+ XFREE(policy->u.hwp);
return 0;
}
@@ -480,7 +476,7 @@ static int cf_check hwp_cpufreq_cpu_exit(struct
cpufreq_policy *policy)
static void cf_check hwp_set_misc_turbo(void *info)
{
const struct cpufreq_policy *policy = info;
- struct hwp_drv_data *data = per_cpu(hwp_drv_data, policy->cpu);
+ struct hwp_drv_data *data = policy->u.hwp;
uint64_t msr;
data->ret = 0;
@@ -511,7 +507,7 @@ static int cf_check hwp_cpufreq_update(unsigned int cpu,
struct cpufreq_policy *
{
on_selected_cpus(cpumask_of(cpu), hwp_set_misc_turbo, policy, 1);
- return per_cpu(hwp_drv_data, cpu)->ret;
+ return policy->u.hwp->ret;
}
#endif /* CONFIG_PM_OP */
@@ -531,9 +527,10 @@ hwp_cpufreq_driver = {
int get_hwp_para(unsigned int cpu,
struct xen_get_cppc_para *cppc_para)
{
- const struct hwp_drv_data *data = per_cpu(hwp_drv_data, cpu);
+ const struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_policy, cpu);
+ const struct hwp_drv_data *data;
- if ( data == NULL )
+ if ( !policy || !(data = policy->u.hwp) )
return -ENODATA;
cppc_para->features =
@@ -554,8 +551,7 @@ int get_hwp_para(unsigned int cpu,
int set_hwp_para(struct cpufreq_policy *policy,
struct xen_set_cppc_para *set_cppc)
{
- unsigned int cpu = policy->cpu;
- struct hwp_drv_data *data = per_cpu(hwp_drv_data, cpu);
+ struct hwp_drv_data *data = policy->u.hwp;
bool cleared_act_window = false;
if ( data == NULL )
diff --git a/xen/include/acpi/cpufreq/cpufreq.h
b/xen/include/acpi/cpufreq/cpufreq.h
index 5d4881eea8..c0ecd690c5 100644
--- a/xen/include/acpi/cpufreq/cpufreq.h
+++ b/xen/include/acpi/cpufreq/cpufreq.h
@@ -62,6 +62,7 @@ struct perf_limits {
uint32_t min_policy_pct;
};
+struct hwp_drv_data;
struct cpufreq_policy {
cpumask_var_t cpus; /* affected CPUs */
unsigned int shared_type; /* ANY or ALL affected CPUs
@@ -81,6 +82,11 @@ struct cpufreq_policy {
int8_t turbo; /* tristate flag: 0 for unsupported
* -1 for disable, 1 for enabled
* See CPUFREQ_TURBO_* below for defines */
+ union {
+#ifdef CONFIG_INTEL
+ struct hwp_drv_data *hwp; /* Driver data for Intel HWP */
+#endif
+ } u;
};
DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |