[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Fix a cpufreq userspace limitation bug



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.