[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Add cpufreq governors: performance, powersave, userspace
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1228915634 0 # Node ID 9ba1541d6dc2d6c6e6c7cf0a57ef8a1f0ea9793d # Parent b73f3646a17fa5fb9fa8edd0a5a4d70dd3353c15 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@xxxxxxxxx> --- xen/drivers/cpufreq/Makefile | 1 xen/drivers/cpufreq/cpufreq.c | 48 ++++++++ xen/drivers/cpufreq/cpufreq_misc_governors.c | 158 +++++++++++++++++++++++++++ xen/drivers/cpufreq/cpufreq_ondemand.c | 12 ++ xen/include/acpi/cpufreq/cpufreq.h | 3 5 files changed, 222 insertions(+) diff -r b73f3646a17f -r 9ba1541d6dc2 xen/drivers/cpufreq/Makefile --- a/xen/drivers/cpufreq/Makefile Wed Dec 10 13:14:13 2008 +0000 +++ b/xen/drivers/cpufreq/Makefile Wed Dec 10 13:27:14 2008 +0000 @@ -1,3 +1,4 @@ obj-y += cpufreq.o obj-y += cpufreq.o obj-y += cpufreq_ondemand.o +obj-y += cpufreq_misc_governors.o obj-y += utility.o diff -r b73f3646a17f -r 9ba1541d6dc2 xen/drivers/cpufreq/cpufreq.c --- a/xen/drivers/cpufreq/cpufreq.c Wed Dec 10 13:14:13 2008 +0000 +++ b/xen/drivers/cpufreq/cpufreq.c Wed Dec 10 13:27:14 2008 +0000 @@ -33,6 +33,7 @@ #include <xen/cpumask.h> #include <xen/list.h> #include <xen/sched.h> +#include <xen/string.h> #include <xen/timer.h> #include <xen/xmalloc.h> #include <xen/guest_access.h> @@ -51,6 +52,53 @@ struct cpufreq_dom { struct list_head node; }; static LIST_HEAD(cpufreq_dom_list_head); + +static LIST_HEAD(cpufreq_governor_list); + +static struct cpufreq_governor *__find_governor(const char *governor) +{ + struct cpufreq_governor *t; + + if (!governor) + return NULL; + + list_for_each_entry(t, &cpufreq_governor_list, governor_list) + if (!strnicmp(governor, t->name, CPUFREQ_NAME_LEN)) + return t; + + return NULL; +} + +int cpufreq_register_governor(struct cpufreq_governor *governor) +{ + if (!governor) + return -EINVAL; + + if (__find_governor(governor->name) != NULL) + return -EEXIST; + + list_add(&governor->governor_list, &cpufreq_governor_list); + return 0; +} + +int cpufreq_unregister_governor(struct cpufreq_governor *governor) +{ + int cpu = smp_processor_id(); + struct cpufreq_policy *policy = cpufreq_cpu_policy[cpu]; + + if (!governor || !policy) + return -EINVAL; + + /* error if unregister current cpufreq governor */ + if (governor == policy->governor) + return -EBUSY; + + if (__find_governor(governor->name) == NULL) + return -ENOENT; + + list_del(&governor->governor_list); + return 0; +} int cpufreq_limit_change(unsigned int cpu) { diff -r b73f3646a17f -r 9ba1541d6dc2 xen/drivers/cpufreq/cpufreq_misc_governors.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c Wed Dec 10 13:27:14 2008 +0000 @@ -0,0 +1,158 @@ +/* + * xen/drivers/cpufreq/cpufreq_misc_gov.c + * + * Copyright (C) 2001 Russell King + * (C) 2002 - 2004 Dominik Brodowski <linux@xxxxxxxx> + * + * Nov 2008 Liu Jinsong <jinsong.liu@xxxxxxxxx> + * Porting cpufreq_userspace.c, cpufreq_performance.c, and + * cpufreq_powersave.c from Liunx 2.6.23 to Xen hypervisor + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <xen/init.h> +#include <xen/sched.h> +#include <acpi/cpufreq/cpufreq.h> + + +/* + * cpufreq userspace governor + */ +static int cpufreq_governor_userspace(struct cpufreq_policy *policy, + unsigned int event) +{ + int ret = 0; + + if (!policy) + return -EINVAL; + + switch (event) { + case CPUFREQ_GOV_START: + case CPUFREQ_GOV_STOP: + break; + case CPUFREQ_GOV_LIMITS: + if (policy->max < policy->cur) + ret = __cpufreq_driver_target(policy, policy->max, + CPUFREQ_RELATION_H); + else if (policy->min > policy->cur) + ret = __cpufreq_driver_target(policy, policy->min, + CPUFREQ_RELATION_L); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +struct cpufreq_governor cpufreq_gov_userspace = { + .name = "userspace", + .governor = cpufreq_governor_userspace, +}; + +static int __init cpufreq_gov_userspace_init(void) +{ + return cpufreq_register_governor(&cpufreq_gov_userspace); +} +__initcall(cpufreq_gov_userspace_init); + +static void cpufreq_gov_userspace_exit(void) +{ + cpufreq_unregister_governor(&cpufreq_gov_userspace); +} +__exitcall(cpufreq_gov_userspace_exit); + + +/* + * cpufreq performance governor + */ +static int cpufreq_governor_performance(struct cpufreq_policy *policy, + unsigned int event) +{ + int ret = 0; + + if (!policy) + return -EINVAL; + + switch (event) { + case CPUFREQ_GOV_START: + case CPUFREQ_GOV_STOP: + break; + case CPUFREQ_GOV_LIMITS: + ret = __cpufreq_driver_target(policy, policy->max, + CPUFREQ_RELATION_H); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +struct cpufreq_governor cpufreq_gov_performance = { + .name = "performance", + .governor = cpufreq_governor_performance, +}; + +static int __init cpufreq_gov_performance_init(void) +{ + return cpufreq_register_governor(&cpufreq_gov_performance); +} +__initcall(cpufreq_gov_performance_init); + +static void cpufreq_gov_performance_exit(void) +{ + cpufreq_unregister_governor(&cpufreq_gov_performance); +} +__exitcall(cpufreq_gov_performance_exit); + + +/* + * cpufreq powersave governor + */ +static int cpufreq_governor_powersave(struct cpufreq_policy *policy, + unsigned int event) +{ + int ret = 0; + + if (!policy) + return -EINVAL; + + switch (event) { + case CPUFREQ_GOV_START: + case CPUFREQ_GOV_STOP: + break; + case CPUFREQ_GOV_LIMITS: + ret = __cpufreq_driver_target(policy, policy->min, + CPUFREQ_RELATION_L); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +struct cpufreq_governor cpufreq_gov_powersave = { + .name = "powersave", + .governor = cpufreq_governor_powersave, +}; + +static int __init cpufreq_gov_powersave_init(void) +{ + return cpufreq_register_governor(&cpufreq_gov_powersave); +} +__initcall(cpufreq_gov_powersave_init); + +static void cpufreq_gov_powersave_exit(void) +{ + cpufreq_unregister_governor(&cpufreq_gov_powersave); +} +__exitcall(cpufreq_gov_powersave_exit); diff -r b73f3646a17f -r 9ba1541d6dc2 xen/drivers/cpufreq/cpufreq_ondemand.c --- a/xen/drivers/cpufreq/cpufreq_ondemand.c Wed Dec 10 13:14:13 2008 +0000 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c Wed Dec 10 13:27:14 2008 +0000 @@ -262,6 +262,18 @@ struct cpufreq_governor cpufreq_gov_dbs .name = "ondemand", .governor = cpufreq_governor_dbs, }; + +static int __init cpufreq_gov_dbs_init(void) +{ + return cpufreq_register_governor(&cpufreq_gov_dbs); +} +__initcall(cpufreq_gov_dbs_init); + +static void cpufreq_gov_dbs_exit(void) +{ + cpufreq_unregister_governor(&cpufreq_gov_dbs); +} +__exitcall(cpufreq_gov_dbs_exit); void __init cpufreq_cmdline_parse(char *str) { diff -r b73f3646a17f -r 9ba1541d6dc2 xen/include/acpi/cpufreq/cpufreq.h --- a/xen/include/acpi/cpufreq/cpufreq.h Wed Dec 10 13:14:13 2008 +0000 +++ b/xen/include/acpi/cpufreq/cpufreq.h Wed Dec 10 13:27:14 2008 +0000 @@ -84,9 +84,12 @@ struct cpufreq_governor { char name[CPUFREQ_NAME_LEN]; int (*governor)(struct cpufreq_policy *policy, unsigned int event); + struct list_head governor_list; }; extern struct cpufreq_governor cpufreq_gov_dbs; +extern int cpufreq_register_governor(struct cpufreq_governor *governor); +extern int cpufreq_unregister_governor(struct cpufreq_governor *governor); #define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_dbs /* pass a target to the cpufreq driver */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |