[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v9 1/8] xen/cpufreq: embed hwp into struct cpufreq_policy{}


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Penny Zheng <Penny.Zheng@xxxxxxx>
  • Date: Thu, 4 Sep 2025 14:35:11 +0800
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=bDJFqa/0jwB62IgSYFWp412EHWmA50CeyfzZTWwYV/M=; b=Ik418D83nLVG40zTXnOqwmJWDEqmljFhbJc2CxNeDDDvwXvQyVE+zQSsKUrXKtfNef3zNOc9XAR2jFbU74PF+/czq6msJ9CCThHSbpgRtaTahgYPKbDVy8e5gXtE+k99rP4/Is4/d+DtKltS2HVEo2NnQaW2P031PkU9dsCd7itJvCrrEpq8MfMH+nEC0+jb3gJEkQ5VjQMEyayhuRiKbCPtgCK0cdcXJR0jQCiiLua4CK5dcBlEOggysCHP2LOmKFHSSOMSFfwc8aQFCh/xEUjxSn5tlEbiGdNrnxsaRseoZ0Jy/bRYv7RAy6ok3NW5rIEXVuDEoqmYoI+8KqTdBQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=HFClEdc6GDfz21vLXIu3qgjpcPlIl6rAcTqmg6W2EhJlHJDNqSBIW9byb3scBqK0lNHwNdCnsFO+6UGA/78HAst8wwbIQpxc0bF4KiPRpdxM6AzNPo32jbDAwOiBe//UYay8zLrp+IeZnQOPxwH42HqWCnK5MSyuHKaTgv/w20Z+fhgUSQ3hMe9BsZoJ2PhsMbSCkq5d9fik6Q7qDDK8l6dY/oBFkn0LnRcOhujykmW7AyXuGj//PYvIfKg4njbWqcIWZ+XjhJLwIG0msoamYsTu4KicAWAXookllO6fCcm9q7u/dsMIybClApJKC7nYgT9k2zgmD7G/TLmH3GED3g==
  • Cc: Penny Zheng <Penny.Zheng@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Thu, 04 Sep 2025 06:35:55 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.