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.w...@intel.com> --- tools/libxc/xc_pm.c | 8 +++---- xen/drivers/acpi/pmstat.c | 57 +++++++++++++++++++++++++++++++++++---------- xen/include/public/sysctl.h | 22 ++++++++++++++--- 3 files changed, 68 insertions(+), 19 deletions(-) diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c index 5a7148e..d116c36 100644 --- a/tools/libxc/xc_pm.c +++ b/tools/libxc/xc_pm.c @@ -241,7 +241,7 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid, sysctl.u.pm_op.cmd = GET_CPUFREQ_PARA; sysctl.u.pm_op.cpuid = cpuid; sys_para->cpu_num = user_para->cpu_num; - sys_para->freq_num = user_para->freq_num; + sys_para->num.freq_num = user_para->freq_num; sys_para->gov_num = user_para->gov_num; ret = xc_sysctl(xch, &sysctl); @@ -250,7 +250,7 @@ int xc_get_cpufreq_para(xc_interface *xch, int cpuid, if ( errno == EAGAIN ) { user_para->cpu_num = sys_para->cpu_num; - user_para->freq_num = sys_para->freq_num; + user_para->freq_num = sys_para->num.freq_num; user_para->gov_num = sys_para->gov_num; ret = -errno; } @@ -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..7057234 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,6 +175,11 @@ static int read_scaling_available_governors(char *scaling_available_governors, if ( !scaling_available_governors ) return -EINVAL; + if (is_internal) { + scnprintf(&scaling_available_governors[0], CPUFREQ_NAME_LEN, "%s", "internal"); + return 0; + } + list_for_each_entry(t, &cpufreq_governor_list, governor_list) { i += scnprintf(&scaling_available_governors[i], @@ -203,18 +208,18 @@ 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 ( (op->u.get_para.cpu_num != cpumask_weight(policy->cpus)) || - (op->u.get_para.freq_num != pmpt->perf.state_count) || + (op->u.get_para.num.freq_num != pmpt->perf.state_count) || (op->u.get_para.gov_num != gov_num) ) { op->u.get_para.cpu_num = cpumask_weight(policy->cpus); - op->u.get_para.freq_num = pmpt->perf.state_count; + op->u.get_para.num.freq_num = pmpt->perf.state_count; op->u.get_para.gov_num = gov_num; return -EAGAIN; } @@ -230,13 +235,13 @@ static int get_cpufreq_para(struct xen_sysctl_pm_op *op) return ret; if ( !(scaling_available_frequencies = - xzalloc_array(uint32_t, op->u.get_para.freq_num)) ) + xzalloc_array(uint32_t, op->u.get_para.num.freq_num)) ) return -ENOMEM; - for ( i = 0; i < op->u.get_para.freq_num; i++ ) + for ( i = 0; i < op->u.get_para.num.freq_num; i++ ) scaling_available_frequencies[i] = pmpt->perf.states[i].core_frequency * 1000; ret = copy_to_guest(op->u.get_para.scaling_available_frequencies, - scaling_available_frequencies, op->u.get_para.freq_num); + scaling_available_frequencies, op->u.get_para.num.freq_num); xfree(scaling_available_frequencies); if ( ret ) return ret; @@ -245,7 +250,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,8 +266,15 @@ 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; + op->u.get_para.num.pstates_num = policy->pstates_num; + } 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, @@ -270,7 +282,10 @@ 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] ) + if (policy->policy) + strlcpy(op->u.get_para.scaling_governor, + "internal", CPUFREQ_NAME_LEN); + else if ( policy->governor->name[0] ) strlcpy(op->u.get_para.scaling_governor, policy->governor->name, CPUFREQ_NAME_LEN); else @@ -321,7 +336,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 +363,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..0e351d0 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -298,9 +298,13 @@ typedef struct xen_ondemand xen_ondemand_t; struct xen_get_cpufreq_para { /* IN/OUT variable */ uint32_t cpu_num; - uint32_t freq_num; uint32_t gov_num; + union { + uint32_t freq_num; + uint32_t pstates_num; + } num; + /* for all governors */ /* OUT variable */ XEN_GUEST_HANDLE_64(uint32) affected_cpus; @@ -314,8 +318,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 +350,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@lists.xen.org http://lists.xen.org/xen-devel