From: Wei Wang <wei.w.wang@intel.com>
To: jbeulich@suse.com, andrew.cooper3@citrix.com, xen-devel@lists.xen.org
Cc: Wei Wang <wei.w.wang@intel.com>
Subject: [PATCH v4 10/11] x86/intel_pstate: support the use of intel_pstate in pmstat.c
Date: Thu, 25 Jun 2015 19:17:13 +0800 [thread overview]
Message-ID: <1435231033-22806-1-git-send-email-wei.w.wang@intel.com> (raw)
Add support in the pmstat.c so that the xenpm tool can request to
access the intel_pstate driver.
v4 changes:
1) changed to use the "internal_governor struct";
2) coding style change (indentation of "gov_num++").
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
---
tools/libxc/xc_pm.c | 4 +-
xen/drivers/acpi/pmstat.c | 148 ++++++++++++++++++++++++++++++++++++--------
xen/include/public/sysctl.h | 16 ++++-
3 files changed, 138 insertions(+), 30 deletions(-)
diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c
index 5a7148e..823bab6 100644
--- a/tools/libxc/xc_pm.c
+++ b/tools/libxc/xc_pm.c
@@ -265,8 +265,8 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
user_para->cpuinfo_max_freq = sys_para->cpuinfo_max_freq;
user_para->cpuinfo_min_freq = sys_para->cpuinfo_min_freq;
user_para->scaling_cur_freq = sys_para->scaling_cur_freq;
- user_para->scaling_max_freq = sys_para->scaling_max_freq;
- user_para->scaling_min_freq = sys_para->scaling_min_freq;
+ user_para->scaling_max_freq = sys_para->scaling_max.freq;
+ user_para->scaling_min_freq = sys_para->scaling_min.freq;
user_para->turbo_enabled = sys_para->turbo_enabled;
memcpy(user_para->scaling_driver,
diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
index daac2da..89628aa 100644
--- a/xen/drivers/acpi/pmstat.c
+++ b/xen/drivers/acpi/pmstat.c
@@ -192,22 +192,33 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
uint32_t ret = 0;
const struct processor_pminfo *pmpt;
struct cpufreq_policy *policy;
+ struct perf_limits *limits;
+ struct internal_governor *internal_gov;
uint32_t gov_num = 0;
uint32_t *affected_cpus;
uint32_t *scaling_available_frequencies;
char *scaling_available_governors;
struct list_head *pos;
uint32_t cpu, i, j = 0;
+ uint32_t cur_gov;
pmpt = processor_pminfo[op->cpuid];
policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+ limits = &policy->limits;
+ internal_gov = policy->internal_gov;
+ cur_gov = internal_gov ? internal_gov->cur_gov : 0;
if ( !pmpt || !pmpt->perf.states ||
- !policy || !policy->governor )
+ !policy || (!policy->governor && !policy->internal_gov) )
return -EINVAL;
- list_for_each(pos, &cpufreq_governor_list)
- gov_num++;
+ if (internal_gov)
+ gov_num = internal_gov->gov_num;
+ else
+ {
+ list_for_each(pos, &cpufreq_governor_list)
+ gov_num++;
+ }
if ( (op->u.get_para.cpu_num != cpumask_weight(policy->cpus)) ||
(op->u.get_para.freq_num != pmpt->perf.state_count) ||
@@ -241,28 +252,47 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
if ( ret )
return ret;
- if ( !(scaling_available_governors =
- xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) )
- return -ENOMEM;
- if ( (ret = read_scaling_available_governors(scaling_available_governors,
- gov_num * CPUFREQ_NAME_LEN * sizeof(char))) )
+ if (internal_gov)
{
+ scaling_available_governors = internal_gov->avail_gov;
+ ret = copy_to_guest(op->u.get_para.scaling_available_governors,
+ scaling_available_governors, gov_num * CPUFREQ_NAME_LEN);
+ if ( ret )
+ return ret;
+ }
+ else
+ {
+ if ( !(scaling_available_governors =
+ xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) )
+ return -ENOMEM;
+ if ( (ret = read_scaling_available_governors(scaling_available_governors,
+ gov_num * CPUFREQ_NAME_LEN * sizeof(char))) )
+ {
+ xfree(scaling_available_governors);
+ return ret;
+ }
+ ret = copy_to_guest(op->u.get_para.scaling_available_governors,
+ scaling_available_governors, gov_num * CPUFREQ_NAME_LEN);
xfree(scaling_available_governors);
- return ret;
+ if ( ret )
+ return ret;
}
- ret = copy_to_guest(op->u.get_para.scaling_available_governors,
- scaling_available_governors, gov_num * CPUFREQ_NAME_LEN);
- xfree(scaling_available_governors);
- if ( ret )
- return ret;
-
op->u.get_para.cpuinfo_cur_freq =
cpufreq_driver->get ? cpufreq_driver->get(op->cpuid) : policy->cur;
op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
op->u.get_para.scaling_cur_freq = policy->cur;
- op->u.get_para.scaling_max_freq = policy->max;
- op->u.get_para.scaling_min_freq = policy->min;
+ if (internal_gov)
+ {
+ op->u.get_para.scaling_max.pct = limits->max_perf_pct;
+ op->u.get_para.scaling_min.pct = limits->min_perf_pct;
+ op->u.get_para.scaling_turbo_pct = limits->turbo_pct;
+ }
+ else
+ {
+ op->u.get_para.scaling_max.freq = policy->max;
+ op->u.get_para.scaling_min.freq = policy->min;
+ }
if ( cpufreq_driver->name[0] )
strlcpy(op->u.get_para.scaling_driver,
@@ -270,11 +300,31 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
else
strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
- if ( policy->governor->name[0] )
- strlcpy(op->u.get_para.scaling_governor,
- policy->governor->name, CPUFREQ_NAME_LEN);
- else
- strlcpy(op->u.get_para.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
+ switch (cur_gov)
+ {
+ case INTERNAL_GOV_PERFORMANCE:
+ strlcpy(op->u.get_para.scaling_governor,
+ "performance", CPUFREQ_NAME_LEN);
+ break;
+ case INTERNAL_GOV_POWERSAVE:
+ strlcpy(op->u.get_para.scaling_governor,
+ "powersave", CPUFREQ_NAME_LEN);
+ break;
+ case INTERNAL_GOV_USERSPACE:
+ strlcpy(op->u.get_para.scaling_governor,
+ "userspace", CPUFREQ_NAME_LEN);
+ break;
+ case INTERNAL_GOV_ONDEMAND:
+ strlcpy(op->u.get_para.scaling_governor,
+ "ondemand", CPUFREQ_NAME_LEN);
+ break;
+ default:
+ if ( policy->governor->name[0] )
+ strlcpy(op->u.get_para.scaling_governor,
+ policy->governor->name, CPUFREQ_NAME_LEN);
+ else
+ strlcpy(op->u.get_para.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
+ }
/* governor specific para */
if ( !strnicmp(op->u.get_para.scaling_governor,
@@ -300,16 +350,36 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
{
struct cpufreq_policy new_policy, *old_policy;
+ struct internal_governor *internal_gov;
old_policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
if ( !old_policy )
return -EINVAL;
+ internal_gov = old_policy->internal_gov;
memcpy(&new_policy, old_policy, sizeof(struct cpufreq_policy));
- new_policy.governor = __find_governor(op->u.set_gov.scaling_governor);
- if (new_policy.governor == NULL)
- return -EINVAL;
+ if (internal_gov && internal_gov->cur_gov)
+ {
+ if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "performance", CPUFREQ_NAME_LEN) )
+ internal_gov->cur_gov = INTERNAL_GOV_PERFORMANCE;
+ else if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "powersave", CPUFREQ_NAME_LEN) )
+ internal_gov->cur_gov = INTERNAL_GOV_POWERSAVE;
+ else if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "userspace", CPUFREQ_NAME_LEN) )
+ internal_gov->cur_gov = INTERNAL_GOV_USERSPACE;
+ else if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "ondemand", CPUFREQ_NAME_LEN) )
+ internal_gov->cur_gov = INTERNAL_GOV_ONDEMAND;
+ }
+ else
+ {
+ new_policy.governor = __find_governor(op->u.set_gov.scaling_governor);
+ if (new_policy.governor == NULL)
+ return -EINVAL;
+ }
return __cpufreq_set_policy(old_policy, &new_policy);
}
@@ -318,10 +388,12 @@ static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
{
int ret = 0;
struct cpufreq_policy *policy;
+ struct internal_governor *internal_gov;
policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+ internal_gov = policy->internal_gov;
- if ( !policy || !policy->governor )
+ if ( !policy || (!policy->governor && !internal_gov) )
return -EINVAL;
switch(op->u.set_para.ctrl_type)
@@ -348,6 +420,30 @@ static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
break;
}
+ case SCALING_MAX_PCT:
+ {
+ struct cpufreq_policy new_policy;
+ struct perf_limits *limits = &new_policy.limits;
+
+ new_policy = *policy;
+ limits->max_perf_pct = clamp_t(uint32_t, op->u.set_para.ctrl_value,
+ limits->min_policy_pct, limits->max_policy_pct);
+ ret = __cpufreq_set_policy(policy, &new_policy);
+ break;
+ }
+
+ case SCALING_MIN_PCT:
+ {
+ struct cpufreq_policy new_policy;
+ struct perf_limits *limits = &new_policy.limits;
+
+ new_policy = *policy;
+ limits->min_perf_pct = clamp_t(uint32_t, op->u.set_para.ctrl_value,
+ limits->min_policy_pct, limits->max_policy_pct);
+ ret = __cpufreq_set_policy(policy, &new_policy);
+ break;
+ }
+
case SCALING_SETSPEED:
{
unsigned int freq =op->u.set_para.ctrl_value;
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 0cf9277..1bb730c 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -315,8 +315,18 @@ struct xen_get_cpufreq_para {
uint32_t scaling_cur_freq;
char scaling_governor[CPUFREQ_NAME_LEN];
- uint32_t scaling_max_freq;
- uint32_t scaling_min_freq;
+
+ union {
+ uint32_t freq;
+ uint32_t pct;
+ } scaling_max;
+
+ union {
+ uint32_t freq;
+ uint32_t pct;
+ } scaling_min;
+
+ uint32_t scaling_turbo_pct;
/* for specific governor */
union {
@@ -337,6 +347,8 @@ struct xen_set_cpufreq_para {
#define SCALING_SETSPEED 3
#define SAMPLING_RATE 4
#define UP_THRESHOLD 5
+ #define SCALING_MAX_PCT 6
+ #define SCALING_MIN_PCT 7
uint32_t ctrl_type;
uint32_t ctrl_value;
--
1.9.1
next reply other threads:[~2015-06-25 11:17 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-25 11:17 Wei Wang [this message]
2015-07-24 14:15 ` [PATCH v4 10/11] x86/intel_pstate: support the use of intel_pstate in pmstat.c Jan Beulich
2015-09-09 8:11 ` Wang, Wei W
2015-09-09 8:31 ` Jan Beulich
2015-09-09 8:49 ` Wang, Wei W
2015-09-09 9:00 ` Jan Beulich
2015-09-09 9:35 ` Wang, Wei W
2015-09-09 10:09 ` Jan Beulich
2015-09-09 10:35 ` Wang, Wei W
2015-09-09 11:57 ` Jan Beulich
2015-09-09 12:56 ` Wang, Wei W
2015-09-09 13:12 ` Jan Beulich
2015-09-09 15:16 ` Wang, Wei W
2015-09-09 15:55 ` Jan Beulich
2015-09-10 5:35 ` Wang, Wei W
2015-09-10 8:16 ` Jan Beulich
2015-09-10 9:33 ` Wang, Wei W
2015-09-10 9:55 ` Jan Beulich
2015-09-10 10:10 ` Wang, Wei W
2015-09-10 10:20 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1435231033-22806-1-git-send-email-wei.w.wang@intel.com \
--to=wei.w.wang@intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).