|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 8/9] x86/intel_pstate: support the use of intel_pstate in pmstat.c
Add support in the pmstat.c so that the xenpm tool can request to
access the intel_pstate driver.
Signed-off-by: Wei Wang <wei.w.wang@xxxxxxxxx>
---
tools/libxc/xc_pm.c | 4 +-
xen/drivers/acpi/pmstat.c | 106 +++++++++++++++++++++++++++++++++++---------
xen/include/public/sysctl.h | 16 ++++++-
3 files changed, 100 insertions(+), 26 deletions(-)
diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c
index 5a7148e..c49d1c0 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.max_freq;
+ user_para->scaling_min_freq = sys_para->scaling_min.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..6da16b0 100644
--- a/xen/drivers/acpi/pmstat.c
+++ b/xen/drivers/acpi/pmstat.c
@@ -167,7 +167,7 @@ int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
* 2. Provide user PM control
*/
static int read_scaling_available_governors(char *scaling_available_governors,
- unsigned int size)
+ unsigned int size, unsigned int is_internal)
{
unsigned int i = 0;
struct cpufreq_governor *t;
@@ -175,12 +175,19 @@ static int read_scaling_available_governors(char
*scaling_available_governors,
if ( !scaling_available_governors )
return -EINVAL;
- list_for_each_entry(t, &cpufreq_governor_list, governor_list)
- {
- i += scnprintf(&scaling_available_governors[i],
- CPUFREQ_NAME_LEN, "%s ", t->name);
- if ( i > size )
- return -EINVAL;
+ if (is_internal) {
+ i += scnprintf(&scaling_available_governors[0], CPUFREQ_NAME_LEN, "%s
", "performance");
+ i += scnprintf(&scaling_available_governors[i], CPUFREQ_NAME_LEN, "%s
", "powersave");
+ i += scnprintf(&scaling_available_governors[i], CPUFREQ_NAME_LEN, "%s
", "userspace");
+ i += scnprintf(&scaling_available_governors[i], CPUFREQ_NAME_LEN, "%s
", "ondemand");
+ } else {
+ list_for_each_entry(t, &cpufreq_governor_list, governor_list)
+ {
+ i += scnprintf(&scaling_available_governors[i],
+ CPUFREQ_NAME_LEN, "%s ", t->name);
+ if ( i > size )
+ return -EINVAL;
+ }
}
scaling_available_governors[i-1] = '\0';
@@ -203,11 +210,15 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
if ( !pmpt || !pmpt->perf.states ||
- !policy || !policy->governor )
+ !policy || (!policy->governor && !policy->policy) )
return -EINVAL;
- list_for_each(pos, &cpufreq_governor_list)
- gov_num++;
+ if (policy->policy)
+ gov_num = 4;
+ 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) ||
@@ -245,7 +256,7 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
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))) )
+ gov_num * CPUFREQ_NAME_LEN * sizeof(char), policy->policy)) )
{
xfree(scaling_available_governors);
return ret;
@@ -261,29 +272,47 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
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 (policy->policy) {
+ op->u.get_para.scaling_max.max_perf_pct = policy->max_perf_pct;
+ op->u.get_para.scaling_min.min_perf_pct = policy->min_perf_pct;
+ op->u.get_para.scaling_turbo_pct = policy->turbo_pct;
+ } else {
+ op->u.get_para.scaling_max.max_freq = policy->max;
+ op->u.get_para.scaling_min.min_freq = policy->min;
+ }
if ( cpufreq_driver->name[0] )
- strlcpy(op->u.get_para.scaling_driver,
+ strlcpy(op->u.get_para.scaling_driver,
cpufreq_driver->name, CPUFREQ_NAME_LEN);
else
strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
- if ( policy->governor->name[0] )
- strlcpy(op->u.get_para.scaling_governor,
+ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
+ strlcpy(op->u.get_para.scaling_governor,
+ "performance", CPUFREQ_NAME_LEN);
+ else if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
+ strlcpy(op->u.get_para.scaling_governor,
+ "powersave", CPUFREQ_NAME_LEN);
+ else if (policy->policy == CPUFREQ_POLICY_USERSPACE)
+ strlcpy(op->u.get_para.scaling_governor,
+ "userspace", CPUFREQ_NAME_LEN);
+ else if (policy->policy == CPUFREQ_POLICY_ONDEMAND)
+ strlcpy(op->u.get_para.scaling_governor,
+ "ondemand", CPUFREQ_NAME_LEN);
+ else 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,
+ if ( !strnicmp(op->u.get_para.scaling_governor,
"userspace", CPUFREQ_NAME_LEN) )
{
op->u.get_para.u.userspace.scaling_setspeed = policy->cur;
}
- if ( !strnicmp(op->u.get_para.scaling_governor,
+ if ( !strnicmp(op->u.get_para.scaling_governor,
"ondemand", CPUFREQ_NAME_LEN) )
{
ret = get_cpufreq_ondemand_para(
@@ -307,9 +336,24 @@ static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
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 (old_policy->policy) {
+ if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "performance", CPUFREQ_NAME_LEN) )
+ old_policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ else if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "powersave", CPUFREQ_NAME_LEN) )
+ old_policy->policy = CPUFREQ_POLICY_POWERSAVE;
+ else if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "userspace", CPUFREQ_NAME_LEN) )
+ old_policy->policy = CPUFREQ_POLICY_USERSPACE;
+ else if ( !strnicmp(op->u.set_gov.scaling_governor,
+ "ondemand", CPUFREQ_NAME_LEN) )
+ old_policy->policy = CPUFREQ_POLICY_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);
}
@@ -321,7 +365,7 @@ static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
- if ( !policy || !policy->governor )
+ if ( !policy || (!policy->governor && !policy->policy) )
return -EINVAL;
switch(op->u.set_para.ctrl_type)
@@ -348,6 +392,24 @@ static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
break;
}
+ case SCALING_MAX_PCT:
+ {
+ struct cpufreq_policy new_policy;
+ memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+ new_policy.max_perf_pct = clamp_t(int, op->u.set_para.ctrl_value, 0,
100);
+ ret = __cpufreq_set_policy(policy, &new_policy);
+ break;
+ }
+
+ case SCALING_MIN_PCT:
+ {
+ struct cpufreq_policy new_policy;
+ memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+ new_policy.min_perf_pct = clamp_t(int, op->u.set_para.ctrl_value, 0,
100);
+ 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 711441f..fe56864 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -314,8 +314,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 max_freq;
+ int32_t max_perf_pct;
+ } scaling_max;
+
+ union {
+ uint32_t min_freq;
+ int32_t min_perf_pct;
+ } scaling_min;
+
+ int32_t scaling_turbo_pct;
/* for specific governor */
union {
@@ -336,6 +346,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
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |