# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1237457364 0
# Node ID fe949f9129b00484b0d1a22a5440db0592f9da92
# Parent 1b27263038b570aadba15b4aaf8a70286e673a4b
Fix a cpufreq userspace limitation bug
Fix a cpufreq userspace limitation bug, so that userspace freq can
return to correct freq when freq_limitation return to high value (like
ppc event)
Signed-off-by: Liu, Jinsong <jinsong.liu@xxxxxxxxx>=
---
xen/drivers/acpi/pmstat.c | 9 --
xen/drivers/cpufreq/cpufreq_misc_governors.c | 83 +++++++++++++++++----------
xen/include/acpi/cpufreq/cpufreq.h | 2
3 files changed, 58 insertions(+), 36 deletions(-)
diff -r 1b27263038b5 -r fe949f9129b0 xen/drivers/acpi/pmstat.c
--- a/xen/drivers/acpi/pmstat.c Thu Mar 19 10:08:48 2009 +0000
+++ b/xen/drivers/acpi/pmstat.c Thu Mar 19 10:09:24 2009 +0000
@@ -368,14 +368,7 @@ static int set_cpufreq_para(struct xen_s
if ( !strnicmp(policy->governor->name,
"userspace", CPUFREQ_NAME_LEN) )
- {
- if ( freq < policy->min )
- freq = policy->min;
- if ( freq > policy->max )
- freq = policy->max;
-
- ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
- }
+ ret = write_userspace_scaling_setspeed(op->cpuid, freq);
else
ret = -EINVAL;
diff -r 1b27263038b5 -r fe949f9129b0
xen/drivers/cpufreq/cpufreq_misc_governors.c
--- a/xen/drivers/cpufreq/cpufreq_misc_governors.c Thu Mar 19 10:08:48
2009 +0000
+++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c Thu Mar 19 10:09:24
2009 +0000
@@ -18,50 +18,77 @@
#include <xen/sched.h>
#include <acpi/cpufreq/cpufreq.h>
-static unsigned int usr_speed;
-
/*
* cpufreq userspace governor
*/
+static unsigned int cpu_set_freq[NR_CPUS];
+
static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
unsigned int event)
{
int ret = 0;
- unsigned int freq;
-
- if (!policy)
- return -EINVAL;
-
- switch (event) {
- case CPUFREQ_GOV_START:
- case CPUFREQ_GOV_STOP:
- break;
- case CPUFREQ_GOV_LIMITS:
- freq = usr_speed ? : policy->cur;
- if (policy->max < freq)
+ unsigned int cpu;
+
+ if (unlikely(!policy) ||
+ unlikely(!cpu_online(cpu = policy->cpu)))
+ return -EINVAL;
+
+ switch (event) {
+ case CPUFREQ_GOV_START:
+ if (!cpu_set_freq[cpu])
+ cpu_set_freq[cpu] = policy->cur;
+ break;
+ case CPUFREQ_GOV_STOP:
+ cpu_set_freq[cpu] = 0;
+ break;
+ case CPUFREQ_GOV_LIMITS:
+ if (policy->max < cpu_set_freq[cpu])
ret = __cpufreq_driver_target(policy, policy->max,
CPUFREQ_RELATION_H);
- else if (policy->min > freq)
+ else if (policy->min > cpu_set_freq[cpu])
ret = __cpufreq_driver_target(policy, policy->min,
CPUFREQ_RELATION_L);
- else if (usr_speed)
- ret = __cpufreq_driver_target(policy, freq,
- CPUFREQ_RELATION_L);
-
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
+ else
+ ret = __cpufreq_driver_target(policy, cpu_set_freq[cpu],
+ CPUFREQ_RELATION_L);
+
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq)
+{
+ struct cpufreq_policy *policy = cpufreq_cpu_policy[cpu];
+
+ if (!cpu_online(cpu) || !policy)
+ return -EINVAL;
+
+ cpu_set_freq[cpu] = freq;
+
+ if (freq < policy->min)
+ freq = policy->min;
+ if (freq > policy->max)
+ freq = policy->max;
+
+ return __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
}
static void __init
cpufreq_userspace_handle_option(const char *name, const char *val)
{
- if (!strcmp(name, "speed") && val)
- usr_speed = simple_strtoul(val, NULL, 0);
+ if (!strcmp(name, "speed") && val) {
+ unsigned int usr_cmdline_freq;
+ unsigned int cpu;
+
+ usr_cmdline_freq = simple_strtoul(val, NULL, 0);
+ for (cpu = 0; cpu < NR_CPUS; cpu++)
+ cpu_set_freq[cpu] = usr_cmdline_freq;
+ }
}
struct cpufreq_governor cpufreq_gov_userspace = {
diff -r 1b27263038b5 -r fe949f9129b0 xen/include/acpi/cpufreq/cpufreq.h
--- a/xen/include/acpi/cpufreq/cpufreq.h Thu Mar 19 10:08:48 2009 +0000
+++ b/xen/include/acpi/cpufreq/cpufreq.h Thu Mar 19 10:09:24 2009 +0000
@@ -227,4 +227,6 @@ int get_cpufreq_ondemand_para(uint32_t *
uint32_t *up_threshold);
int write_ondemand_sampling_rate(unsigned int sampling_rate);
int write_ondemand_up_threshold(unsigned int up_threshold);
+
+int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
#endif /* __XEN_CPUFREQ_PM_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|