|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v5 14/18] xen/cpufreq: introduce GET_CPUFREQ_CPPC sub-cmd
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |