ia64/xen-unstable

changeset 18903:9ba1541d6dc2

Add cpufreq governors: performance, powersave, userspace

This patch add 3 more governors beside original running ondemand
cpufreq governor.
performance governor is with best performance, keeping cpu always
running at highest freq;
powersave governor is with best power save effect, keeping cpu always
running at lowest freq;
userspace governor provide user setting freq ability;

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Dec 10 13:27:14 2008 +0000 (2008-12-10)
parents b73f3646a17f
children 605ef79ee46c
files xen/drivers/cpufreq/Makefile xen/drivers/cpufreq/cpufreq.c xen/drivers/cpufreq/cpufreq_misc_governors.c xen/drivers/cpufreq/cpufreq_ondemand.c xen/include/acpi/cpufreq/cpufreq.h
line diff
     1.1 --- a/xen/drivers/cpufreq/Makefile	Wed Dec 10 13:14:13 2008 +0000
     1.2 +++ b/xen/drivers/cpufreq/Makefile	Wed Dec 10 13:27:14 2008 +0000
     1.3 @@ -1,3 +1,4 @@
     1.4  obj-y += cpufreq.o
     1.5  obj-y += cpufreq_ondemand.o
     1.6 +obj-y += cpufreq_misc_governors.o
     1.7  obj-y += utility.o
     2.1 --- a/xen/drivers/cpufreq/cpufreq.c	Wed Dec 10 13:14:13 2008 +0000
     2.2 +++ b/xen/drivers/cpufreq/cpufreq.c	Wed Dec 10 13:27:14 2008 +0000
     2.3 @@ -33,6 +33,7 @@
     2.4  #include <xen/cpumask.h>
     2.5  #include <xen/list.h>
     2.6  #include <xen/sched.h>
     2.7 +#include <xen/string.h>
     2.8  #include <xen/timer.h>
     2.9  #include <xen/xmalloc.h>
    2.10  #include <xen/guest_access.h>
    2.11 @@ -52,6 +53,53 @@ struct cpufreq_dom {
    2.12  };
    2.13  static LIST_HEAD(cpufreq_dom_list_head);
    2.14  
    2.15 +static LIST_HEAD(cpufreq_governor_list);
    2.16 +
    2.17 +static struct cpufreq_governor *__find_governor(const char *governor)
    2.18 +{
    2.19 +    struct cpufreq_governor *t;
    2.20 +
    2.21 +    if (!governor)
    2.22 +        return NULL;
    2.23 +
    2.24 +    list_for_each_entry(t, &cpufreq_governor_list, governor_list)
    2.25 +        if (!strnicmp(governor, t->name, CPUFREQ_NAME_LEN))
    2.26 +            return t;
    2.27 +
    2.28 +    return NULL;
    2.29 +}
    2.30 +
    2.31 +int cpufreq_register_governor(struct cpufreq_governor *governor)
    2.32 +{
    2.33 +    if (!governor)
    2.34 +        return -EINVAL;
    2.35 +
    2.36 +    if (__find_governor(governor->name) != NULL)
    2.37 +        return -EEXIST;
    2.38 +
    2.39 +    list_add(&governor->governor_list, &cpufreq_governor_list);
    2.40 +    return 0;
    2.41 +}
    2.42 +
    2.43 +int cpufreq_unregister_governor(struct cpufreq_governor *governor)
    2.44 +{
    2.45 +    int cpu = smp_processor_id();
    2.46 +    struct cpufreq_policy *policy = cpufreq_cpu_policy[cpu];
    2.47 +
    2.48 +    if (!governor || !policy)
    2.49 +        return -EINVAL;
    2.50 +
    2.51 +    /* error if unregister current cpufreq governor */
    2.52 +    if (governor == policy->governor)
    2.53 +        return -EBUSY;
    2.54 +
    2.55 +    if (__find_governor(governor->name) == NULL)
    2.56 +        return -ENOENT;
    2.57 +
    2.58 +    list_del(&governor->governor_list);
    2.59 +    return 0;
    2.60 +}
    2.61 +
    2.62  int cpufreq_limit_change(unsigned int cpu)
    2.63  {
    2.64      struct processor_performance *perf = &processor_pminfo[cpu]->perf;
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c	Wed Dec 10 13:27:14 2008 +0000
     3.3 @@ -0,0 +1,158 @@
     3.4 +/*
     3.5 + *  xen/drivers/cpufreq/cpufreq_misc_gov.c
     3.6 + *
     3.7 + *  Copyright (C)  2001 Russell King
     3.8 + *            (C)  2002 - 2004 Dominik Brodowski <linux@brodo.de>
     3.9 + *
    3.10 + *     Nov 2008 Liu Jinsong <jinsong.liu@intel.com>
    3.11 + *     Porting cpufreq_userspace.c, cpufreq_performance.c, and 
    3.12 + *     cpufreq_powersave.c from Liunx 2.6.23 to Xen hypervisor
    3.13 + *
    3.14 + * This program is free software; you can redistribute it and/or modify
    3.15 + * it under the terms of the GNU General Public License version 2 as
    3.16 + * published by the Free Software Foundation.
    3.17 + *
    3.18 + */
    3.19 +
    3.20 +#include <xen/init.h>
    3.21 +#include <xen/sched.h>
    3.22 +#include <acpi/cpufreq/cpufreq.h>
    3.23 +
    3.24 +
    3.25 +/*
    3.26 + * cpufreq userspace governor
    3.27 + */
    3.28 +static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
    3.29 +                                      unsigned int event)
    3.30 +{
    3.31 +    int ret = 0;
    3.32 +
    3.33 +    if (!policy)
    3.34 +        return -EINVAL;
    3.35 +
    3.36 +    switch (event) {
    3.37 +    case CPUFREQ_GOV_START:
    3.38 +    case CPUFREQ_GOV_STOP:
    3.39 +        break;
    3.40 +    case CPUFREQ_GOV_LIMITS:
    3.41 +        if (policy->max < policy->cur)
    3.42 +            ret = __cpufreq_driver_target(policy, policy->max,
    3.43 +                        CPUFREQ_RELATION_H);
    3.44 +        else if (policy->min > policy->cur)
    3.45 +            ret = __cpufreq_driver_target(policy, policy->min,
    3.46 +                        CPUFREQ_RELATION_L);
    3.47 +        break;
    3.48 +    default:
    3.49 +        ret = -EINVAL;
    3.50 +        break;
    3.51 +    }
    3.52 +
    3.53 +    return ret;
    3.54 +}
    3.55 +
    3.56 +struct cpufreq_governor cpufreq_gov_userspace = {
    3.57 +    .name = "userspace",
    3.58 +    .governor = cpufreq_governor_userspace,
    3.59 +};
    3.60 +
    3.61 +static int __init cpufreq_gov_userspace_init(void)
    3.62 +{
    3.63 +    return cpufreq_register_governor(&cpufreq_gov_userspace);
    3.64 +}
    3.65 +__initcall(cpufreq_gov_userspace_init);
    3.66 +
    3.67 +static void cpufreq_gov_userspace_exit(void)
    3.68 +{
    3.69 +    cpufreq_unregister_governor(&cpufreq_gov_userspace);
    3.70 +}
    3.71 +__exitcall(cpufreq_gov_userspace_exit);
    3.72 +
    3.73 +
    3.74 +/*
    3.75 + * cpufreq performance governor
    3.76 + */
    3.77 +static int cpufreq_governor_performance(struct cpufreq_policy *policy,
    3.78 +                                      unsigned int event)
    3.79 +{
    3.80 +    int ret = 0;
    3.81 +
    3.82 +    if (!policy)
    3.83 +        return -EINVAL;
    3.84 +
    3.85 +    switch (event) {
    3.86 +    case CPUFREQ_GOV_START:
    3.87 +    case CPUFREQ_GOV_STOP:
    3.88 +        break;
    3.89 +    case CPUFREQ_GOV_LIMITS:
    3.90 +        ret = __cpufreq_driver_target(policy, policy->max,
    3.91 +                        CPUFREQ_RELATION_H);
    3.92 +        break;
    3.93 +    default:
    3.94 +        ret = -EINVAL;
    3.95 +        break;
    3.96 +    }
    3.97 +
    3.98 +    return ret;
    3.99 +}
   3.100 +
   3.101 +struct cpufreq_governor cpufreq_gov_performance = {
   3.102 +    .name = "performance",
   3.103 +    .governor = cpufreq_governor_performance,
   3.104 +};
   3.105 +
   3.106 +static int __init cpufreq_gov_performance_init(void)
   3.107 +{
   3.108 +    return cpufreq_register_governor(&cpufreq_gov_performance);
   3.109 +}
   3.110 +__initcall(cpufreq_gov_performance_init);
   3.111 +
   3.112 +static void cpufreq_gov_performance_exit(void)
   3.113 +{
   3.114 +    cpufreq_unregister_governor(&cpufreq_gov_performance);
   3.115 +}
   3.116 +__exitcall(cpufreq_gov_performance_exit);
   3.117 +
   3.118 +
   3.119 +/*
   3.120 + * cpufreq powersave governor
   3.121 + */
   3.122 +static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
   3.123 +                                      unsigned int event)
   3.124 +{
   3.125 +    int ret = 0;
   3.126 +
   3.127 +    if (!policy)
   3.128 +        return -EINVAL;
   3.129 +
   3.130 +    switch (event) {
   3.131 +    case CPUFREQ_GOV_START:
   3.132 +    case CPUFREQ_GOV_STOP:
   3.133 +        break;
   3.134 +    case CPUFREQ_GOV_LIMITS:
   3.135 +        ret = __cpufreq_driver_target(policy, policy->min,
   3.136 +                        CPUFREQ_RELATION_L);
   3.137 +        break;
   3.138 +    default:
   3.139 +        ret = -EINVAL;
   3.140 +        break;
   3.141 +    }
   3.142 +
   3.143 +    return ret;
   3.144 +}
   3.145 +
   3.146 +struct cpufreq_governor cpufreq_gov_powersave = {
   3.147 +    .name = "powersave",
   3.148 +    .governor = cpufreq_governor_powersave,
   3.149 +};
   3.150 +
   3.151 +static int __init cpufreq_gov_powersave_init(void)
   3.152 +{
   3.153 +    return cpufreq_register_governor(&cpufreq_gov_powersave);
   3.154 +}
   3.155 +__initcall(cpufreq_gov_powersave_init);
   3.156 +
   3.157 +static void cpufreq_gov_powersave_exit(void)
   3.158 +{
   3.159 +    cpufreq_unregister_governor(&cpufreq_gov_powersave);
   3.160 +}
   3.161 +__exitcall(cpufreq_gov_powersave_exit);
     4.1 --- a/xen/drivers/cpufreq/cpufreq_ondemand.c	Wed Dec 10 13:14:13 2008 +0000
     4.2 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c	Wed Dec 10 13:27:14 2008 +0000
     4.3 @@ -263,6 +263,18 @@ struct cpufreq_governor cpufreq_gov_dbs 
     4.4      .governor = cpufreq_governor_dbs,
     4.5  };
     4.6  
     4.7 +static int __init cpufreq_gov_dbs_init(void)
     4.8 +{
     4.9 +    return cpufreq_register_governor(&cpufreq_gov_dbs);
    4.10 +}
    4.11 +__initcall(cpufreq_gov_dbs_init);
    4.12 +
    4.13 +static void cpufreq_gov_dbs_exit(void)
    4.14 +{
    4.15 +    cpufreq_unregister_governor(&cpufreq_gov_dbs);
    4.16 +}
    4.17 +__exitcall(cpufreq_gov_dbs_exit);
    4.18 +
    4.19  void __init cpufreq_cmdline_parse(char *str)
    4.20  {
    4.21      do {
     5.1 --- a/xen/include/acpi/cpufreq/cpufreq.h	Wed Dec 10 13:14:13 2008 +0000
     5.2 +++ b/xen/include/acpi/cpufreq/cpufreq.h	Wed Dec 10 13:27:14 2008 +0000
     5.3 @@ -84,9 +84,12 @@ struct cpufreq_governor {
     5.4      char    name[CPUFREQ_NAME_LEN];
     5.5      int     (*governor)(struct cpufreq_policy *policy,
     5.6                          unsigned int event);
     5.7 +    struct list_head governor_list;
     5.8  };
     5.9  
    5.10  extern struct cpufreq_governor cpufreq_gov_dbs;
    5.11 +extern int cpufreq_register_governor(struct cpufreq_governor *governor);
    5.12 +extern int cpufreq_unregister_governor(struct cpufreq_governor *governor);
    5.13  #define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs
    5.14  
    5.15  /* pass a target to the cpufreq driver */