ia64/xen-unstable

changeset 19398:fe949f9129b0

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@intel.com>=
author Keir Fraser <keir.fraser@citrix.com>
date Thu Mar 19 10:09:24 2009 +0000 (2009-03-19)
parents 1b27263038b5
children cbdc022b0035
files xen/drivers/acpi/pmstat.c xen/drivers/cpufreq/cpufreq_misc_governors.c xen/include/acpi/cpufreq/cpufreq.h
line diff
     1.1 --- a/xen/drivers/acpi/pmstat.c	Thu Mar 19 10:08:48 2009 +0000
     1.2 +++ b/xen/drivers/acpi/pmstat.c	Thu Mar 19 10:09:24 2009 +0000
     1.3 @@ -368,14 +368,7 @@ static int set_cpufreq_para(struct xen_s
     1.4  
     1.5          if ( !strnicmp(policy->governor->name,
     1.6                         "userspace", CPUFREQ_NAME_LEN) )
     1.7 -        {
     1.8 -            if ( freq < policy->min )
     1.9 -                freq = policy->min;
    1.10 -            if ( freq > policy->max )
    1.11 -                freq = policy->max;
    1.12 -
    1.13 -            ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
    1.14 -        }
    1.15 +            ret = write_userspace_scaling_setspeed(op->cpuid, freq);
    1.16          else
    1.17              ret = -EINVAL;
    1.18  
     2.1 --- a/xen/drivers/cpufreq/cpufreq_misc_governors.c	Thu Mar 19 10:08:48 2009 +0000
     2.2 +++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c	Thu Mar 19 10:09:24 2009 +0000
     2.3 @@ -18,34 +18,38 @@
     2.4  #include <xen/sched.h>
     2.5  #include <acpi/cpufreq/cpufreq.h>
     2.6  
     2.7 -static unsigned int usr_speed;
     2.8 -
     2.9  /*
    2.10   * cpufreq userspace governor
    2.11   */
    2.12 +static unsigned int cpu_set_freq[NR_CPUS];
    2.13 +
    2.14  static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
    2.15                                        unsigned int event)
    2.16  {
    2.17      int ret = 0;
    2.18 -    unsigned int freq;
    2.19 +    unsigned int cpu;
    2.20  
    2.21 -    if (!policy)
    2.22 +    if (unlikely(!policy) || 
    2.23 +        unlikely(!cpu_online(cpu = policy->cpu)))
    2.24          return -EINVAL;
    2.25  
    2.26      switch (event) {
    2.27      case CPUFREQ_GOV_START:
    2.28 +        if (!cpu_set_freq[cpu])
    2.29 +            cpu_set_freq[cpu] = policy->cur;
    2.30 +        break;
    2.31      case CPUFREQ_GOV_STOP:
    2.32 +        cpu_set_freq[cpu] = 0;
    2.33          break;
    2.34      case CPUFREQ_GOV_LIMITS:
    2.35 -        freq = usr_speed ? : policy->cur;
    2.36 -        if (policy->max < freq)
    2.37 +        if (policy->max < cpu_set_freq[cpu])
    2.38              ret = __cpufreq_driver_target(policy, policy->max,
    2.39                          CPUFREQ_RELATION_H);
    2.40 -        else if (policy->min > freq)
    2.41 +        else if (policy->min > cpu_set_freq[cpu])
    2.42              ret = __cpufreq_driver_target(policy, policy->min,
    2.43                          CPUFREQ_RELATION_L);
    2.44 -        else if (usr_speed)
    2.45 -            ret = __cpufreq_driver_target(policy, freq,
    2.46 +        else
    2.47 +            ret = __cpufreq_driver_target(policy, cpu_set_freq[cpu],
    2.48                          CPUFREQ_RELATION_L);
    2.49  
    2.50          break;
    2.51 @@ -57,11 +61,34 @@ static int cpufreq_governor_userspace(st
    2.52      return ret;
    2.53  }
    2.54  
    2.55 +int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq)
    2.56 +{
    2.57 +    struct cpufreq_policy *policy = cpufreq_cpu_policy[cpu];
    2.58 +
    2.59 +    if (!cpu_online(cpu) || !policy)
    2.60 +        return -EINVAL;
    2.61 +
    2.62 +    cpu_set_freq[cpu] = freq;
    2.63 +
    2.64 +    if (freq < policy->min)
    2.65 +        freq = policy->min;
    2.66 +    if (freq > policy->max)
    2.67 +        freq = policy->max;
    2.68 +
    2.69 +    return __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
    2.70 +}
    2.71 +
    2.72  static void __init 
    2.73  cpufreq_userspace_handle_option(const char *name, const char *val)
    2.74  {
    2.75 -    if (!strcmp(name, "speed") && val)
    2.76 -        usr_speed = simple_strtoul(val, NULL, 0);
    2.77 +    if (!strcmp(name, "speed") && val) {
    2.78 +        unsigned int usr_cmdline_freq;
    2.79 +        unsigned int cpu;
    2.80 +
    2.81 +        usr_cmdline_freq = simple_strtoul(val, NULL, 0);
    2.82 +        for (cpu = 0; cpu < NR_CPUS; cpu++)
    2.83 +            cpu_set_freq[cpu] = usr_cmdline_freq;
    2.84 +    }
    2.85  }
    2.86  
    2.87  struct cpufreq_governor cpufreq_gov_userspace = {
     3.1 --- a/xen/include/acpi/cpufreq/cpufreq.h	Thu Mar 19 10:08:48 2009 +0000
     3.2 +++ b/xen/include/acpi/cpufreq/cpufreq.h	Thu Mar 19 10:09:24 2009 +0000
     3.3 @@ -227,4 +227,6 @@ int get_cpufreq_ondemand_para(uint32_t *
     3.4                                uint32_t *up_threshold);
     3.5  int write_ondemand_sampling_rate(unsigned int sampling_rate);
     3.6  int write_ondemand_up_threshold(unsigned int up_threshold);
     3.7 +
     3.8 +int write_userspace_scaling_setspeed(unsigned int cpu, unsigned int freq);
     3.9  #endif /* __XEN_CPUFREQ_PM_H__ */