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

[PATCH v5 14/18] xen/cpufreq: introduce GET_CPUFREQ_CPPC sub-cmd


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Penny Zheng <Penny.Zheng@xxxxxxx>
  • Date: Tue, 27 May 2025 16:48:29 +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=vXUlUm4d0wql5IcMZNTgxdbV0uwQON7fY64Zus5RrVI=; b=MwCaYnyTtXjkcu4Z3cFGmVXVyU8+XQrbddqLbzbF+1HrymDhP6ZCOVbt1XgRvIyX97e2/yg4nbs4qEaTUpkktrMLyreZRvuc3WYPVnaUpw6FVsgg1lapOcauhadsm9V+lFLJ9Eil5ASla+pdgZybc6iihaDqii5NQUeHU+K0LUgtP/nTHy6Fzmzy/AKANgW9mCnFgAtlpCVXvRwvwPRB9VD13MeENdtQGa0kviyJzMm9N+/+p3boNwHbkFqLpwZWkxvZhSx21w0swegQBdRoZlJoyl1PE6d1TDViUEnhh7RdGGYRGZhHAHNboSMNBTmXw+MVpvSGOgGV4fFd4ReWwA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=LcIAPpNUuK1QalVq1OlHwlte4hKmqDq/eECqk4QxjrMsvrQnR39m41ZtWvW0HJ0UaM6u0mq4tVgyzbIOpeVM7WcPRfrQ/l5CIwbFPjjyHNchZ9g9n85WmO+yVr91Xp2btsCH131n47NcKChWrYRHoQ8rtS8JVenRNN9kuw9wI3dzOmJF4fUfKcMQooCj2iLAnwuQmgVlvsqBAY0ikq5CflMyqWQeJCfROtfl7UjJqcXUkHdQJYgHGJtjYJRq18L2d5/bihT9pv4+WZoAJmSiGwPDI0L5trZdX/vRm7HC9iROsUiq9QOnS4dtC2VJOLr6LVb6MzzKPQ7zN0p0RjKNlg==
  • Cc: <ray.huang@xxxxxxx>, Penny Zheng <Penny.Zheng@xxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, "Stefano Stabellini" <sstabellini@xxxxxxxxxx>
  • Delivery-date: Tue, 27 May 2025 08:50:41 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

In amd-cppc passive mode, it's Xen governor which is responsible for
performance tuning, so governor and CPPC could co-exist. That is, both
governor-info and CPPC-info could be printed together via xenpm tool.

To achieve that, "struct xen_cppc_para" needs to be moved out of the union
and also "struct xen_get_cpufreq_para". Also if still putting it in
"struct xen_get_cpufreq_para" (e.g. just move out of union),
"struct xen_get_cpufreq_para" will enlarge too much to further make
xen_sysctl.u exceed 128 bytes.
We introduce a new sub-cmd GET_CPUFREQ_CPPC to specifically print
CPPC-related para and clear cppc print in GET_CPUFREQ_PARA.

Signed-off-by: Penny Zheng <Penny.Zheng@xxxxxxx>
---
v4 -> v5:
- new commit
---
 tools/include/xenctrl.h     |  3 +-
 tools/libs/ctrl/xc_pm.c     | 28 ++++++++++-
 tools/misc/xenpm.c          | 97 ++++++++++++++++++++++++++-----------
 xen/drivers/acpi/pmstat.c   | 18 +++++--
 xen/include/public/sysctl.h |  3 +-
 5 files changed, 116 insertions(+), 33 deletions(-)

diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index 4955981231..79523d2d73 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -1938,7 +1938,6 @@ struct xc_get_cpufreq_para {
                 xc_ondemand_t ondemand;
             } u;
         } s;
-        xc_cppc_para_t cppc_para;
     } u;
 
     int32_t turbo_enabled;
@@ -1953,6 +1952,8 @@ int xc_set_cpufreq_para(xc_interface *xch, int cpuid,
                         int ctrl_type, int ctrl_value);
 int xc_set_cpufreq_cppc(xc_interface *xch, int cpuid,
                         xc_set_cppc_para_t *set_cppc);
+int xc_get_cppc_para(xc_interface *xch, unsigned int cpuid,
+                     xc_cppc_para_t *cppc_para);
 int xc_get_cpufreq_avgfreq(xc_interface *xch, int cpuid, int *avg_freq);
 
 int xc_set_sched_opt_smt(xc_interface *xch, uint32_t value);
diff --git a/tools/libs/ctrl/xc_pm.c b/tools/libs/ctrl/xc_pm.c
index ff7b5ada05..3c9e272aee 100644
--- a/tools/libs/ctrl/xc_pm.c
+++ b/tools/libs/ctrl/xc_pm.c
@@ -289,7 +289,6 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
         CHK_FIELD(s.scaling_min_freq);
         CHK_FIELD(s.u.userspace);
         CHK_FIELD(s.u.ondemand);
-        CHK_FIELD(cppc_para);
 
 #undef CHK_FIELD
 
@@ -367,6 +366,33 @@ int xc_set_cpufreq_cppc(xc_interface *xch, int cpuid,
     return ret;
 }
 
+int xc_get_cppc_para(xc_interface *xch, unsigned int cpuid,
+                     xc_cppc_para_t *cppc_para)
+{
+    int ret;
+    struct xen_sysctl sysctl = {};
+    struct xen_cppc_para *sys_cppc_para = &sysctl.u.pm_op.u.cppc_para;
+
+    if ( !xch  || !cppc_para )
+    {
+        errno = EINVAL;
+        return -1;
+    }
+
+    sysctl.cmd = XEN_SYSCTL_pm_op;
+    sysctl.u.pm_op.cmd = GET_CPUFREQ_CPPC;
+    sysctl.u.pm_op.cpuid = cpuid;
+
+    ret = xc_sysctl(xch, &sysctl);
+    if ( ret )
+        return ret;
+
+    BUILD_BUG_ON(sizeof(*cppc_para) != sizeof(*sys_cppc_para));
+    memcpy(cppc_para, sys_cppc_para, sizeof(*sys_cppc_para));
+
+    return ret;
+}
+
 int xc_get_cpufreq_avgfreq(xc_interface *xch, int cpuid, int *avg_freq)
 {
     int ret = 0;
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index db658ebadd..2a87f7ae8a 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -69,6 +69,7 @@ void show_help(void)
             " set-max-cstate        <num>|'unlimited' [<num2>|'unlimited']\n"
             "                                     set the C-State limitation 
(<num> >= 0) and\n"
             "                                     optionally the C-sub-state 
limitation (<num2> >= 0)\n"
+            " get-cpufreq-cppc      [cpuid]       list cpu cppc parameter of 
CPU <cpuid> or all\n"
             " set-cpufreq-cppc      [cpuid] [balance|performance|powersave] 
<param:val>*\n"
             "                                     set Hardware P-State (HWP) 
parameters\n"
             "                                     on CPU <cpuid> or all if 
omitted.\n"
@@ -812,33 +813,7 @@ static void print_cpufreq_para(int cpuid, struct 
xc_get_cpufreq_para *p_cpufreq)
 
     printf("scaling_driver       : %s\n", p_cpufreq->scaling_driver);
 
-    if ( hwp )
-    {
-        const xc_cppc_para_t *cppc = &p_cpufreq->u.cppc_para;
-
-        printf("cppc variables       :\n");
-        printf("  hardware limits    : lowest [%"PRIu32"] lowest nonlinear 
[%"PRIu32"]\n",
-               cppc->lowest, cppc->lowest_nonlinear);
-        printf("                     : nominal [%"PRIu32"] highest 
[%"PRIu32"]\n",
-               cppc->nominal, cppc->highest);
-        printf("  configured limits  : min [%"PRIu32"] max [%"PRIu32"] energy 
perf [%"PRIu32"]\n",
-               cppc->minimum, cppc->maximum, cppc->energy_perf);
-
-        if ( cppc->features & XEN_SYSCTL_CPPC_FEAT_ACT_WINDOW )
-        {
-            unsigned int activity_window;
-            const char *units;
-
-            activity_window = calculate_activity_window(cppc, &units);
-            printf("                     : activity_window [%"PRIu32" %s]\n",
-                   activity_window, units);
-        }
-
-        printf("                     : desired [%"PRIu32"%s]\n",
-               cppc->desired,
-               cppc->desired ? "" : " hw autonomous");
-    }
-    else
+    if ( !hwp )
     {
         if ( p_cpufreq->gov_num )
             printf("scaling_avail_gov    : %s\n",
@@ -981,6 +956,73 @@ void cpufreq_para_func(int argc, char *argv[])
         show_cpufreq_para_by_cpuid(xc_handle, cpuid);
 }
 
+/* print out parameters about cpu cppc */
+static void print_cppc_para(unsigned int cpuid,
+                            const xc_cppc_para_t *cppc)
+{
+    printf("cpu id               : %u\n", cpuid);
+    printf("cppc variables       :\n");
+    printf("  hardware limits    : lowest [%"PRIu32"] lowest nonlinear 
[%"PRIu32"]\n",
+           cppc->lowest, cppc->lowest_nonlinear);
+    printf("                     : nominal [%"PRIu32"] highest [%"PRIu32"]\n",
+           cppc->nominal, cppc->highest);
+    printf("  configured limits  : min [%"PRIu32"] max [%"PRIu32"] energy perf 
[%"PRIu32"]\n",
+           cppc->minimum, cppc->maximum, cppc->energy_perf);
+
+    if ( cppc->features & XEN_SYSCTL_CPPC_FEAT_ACT_WINDOW )
+    {
+        unsigned int activity_window;
+        const char *units;
+
+        activity_window = calculate_activity_window(cppc, &units);
+        printf("                     : activity_window [%"PRIu32" %s]\n",
+               activity_window, units);
+    }
+
+    printf("                     : desired [%"PRIu32"%s]\n",
+           cppc->desired,
+           cppc->desired ? "" : " hw autonomous");
+    printf("\n");
+}
+
+/* show cpu cppc parameters information on CPU cpuid */
+static int show_cppc_para_by_cpuid(xc_interface *xc_handle, unsigned int cpuid)
+{
+    int ret;
+    xc_cppc_para_t cppc_para;
+
+    ret = xc_get_cppc_para(xc_handle, cpuid, &cppc_para);
+    if ( ret == 0 )
+        print_cppc_para(cpuid, &cppc_para);
+    else if ( errno == ENODEV )
+    {
+        ret = -ENODEV;
+        fprintf(stderr, "CPPC is not available!\n");
+    }
+    else
+        fprintf(stderr, "[CPU%u] failed to get cppc parameter\n", cpuid);
+
+    return ret;
+}
+
+static void cppc_para_func(int argc, char *argv[])
+{
+    int cpuid = -1;
+
+    if ( argc > 0 )
+        parse_cpuid(argv[0], &cpuid);
+
+    if ( cpuid < 0 )
+    {
+        /* show cpu cppc information on all cpus */
+        for ( unsigned int i = 0; i < max_cpu_nr; i++ )
+            if ( show_cppc_para_by_cpuid(xc_handle, i) == -ENODEV )
+                break;
+    }
+    else
+        show_cppc_para_by_cpuid(xc_handle, cpuid);
+}
+
 void scaling_max_freq_func(int argc, char *argv[])
 {
     int cpuid = -1, freq = -1;
@@ -1561,6 +1603,7 @@ struct {
     { "get-cpufreq-average", cpufreq_func },
     { "start", start_gather_func },
     { "get-cpufreq-para", cpufreq_para_func },
+    { "get-cpufreq-cppc", cppc_para_func },
     { "set-cpufreq-cppc", cppc_set_func },
     { "set-scaling-maxfreq", scaling_max_freq_func },
     { "set-scaling-minfreq", scaling_min_freq_func },
diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
index c09e001ec3..6e9178ade1 100644
--- a/xen/drivers/acpi/pmstat.c
+++ b/xen/drivers/acpi/pmstat.c
@@ -253,9 +253,7 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
     else
         strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
 
-    if ( hwp_active() )
-        ret = get_hwp_para(policy->cpu, &op->u.get_para.u.cppc_para);
-    else
+    if ( !hwp_active() )
     {
         if ( !(scaling_available_governors =
                xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) )
@@ -328,6 +326,16 @@ static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
     return __cpufreq_set_policy(old_policy, &new_policy);
 }
 
+static int get_cpufreq_cppc(struct xen_sysctl_pm_op *op)
+{
+    int ret = -ENODEV;
+
+    if ( hwp_active() )
+        ret = get_hwp_para(op->cpuid, &op->u.cppc_para);
+
+    return ret;
+}
+
 static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
 {
     int ret = 0;
@@ -498,6 +506,10 @@ int do_pm_op(struct xen_sysctl_pm_op *op)
         break;
     }
 
+    case GET_CPUFREQ_CPPC:
+        ret = get_cpufreq_cppc(op);
+        break;
+
     case SET_CPUFREQ_CPPC:
         ret = set_cpufreq_cppc(op);
         break;
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index fa431fd983..29872fe508 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -462,7 +462,6 @@ struct xen_get_cpufreq_para {
                 struct  xen_ondemand ondemand;
             } u;
         } s;
-        struct xen_cppc_para cppc_para;
     } u;
 
     int32_t turbo_enabled;
@@ -493,6 +492,7 @@ struct xen_sysctl_pm_op {
     #define SET_CPUFREQ_PARA           (CPUFREQ_PARA | 0x03)
     #define GET_CPUFREQ_AVGFREQ        (CPUFREQ_PARA | 0x04)
     #define SET_CPUFREQ_CPPC           (CPUFREQ_PARA | 0x05)
+    #define GET_CPUFREQ_CPPC           (CPUFREQ_PARA | 0x06)
 
     /* set/reset scheduler power saving option */
     #define XEN_SYSCTL_pm_op_set_sched_opt_smt    0x21
@@ -517,6 +517,7 @@ struct xen_sysctl_pm_op {
     uint32_t cpuid;
     union {
         struct xen_get_cpufreq_para get_para;
+        struct xen_cppc_para        cppc_para;
         struct xen_set_cpufreq_gov  set_gov;
         struct xen_set_cpufreq_para set_para;
         struct xen_set_cppc_para    set_cppc;
-- 
2.34.1




 


Rackspace

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