# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1230559726 0
# Node ID 5544a96572bfc4ef3abd57d7a060f178c0357abe
# Parent e0301796fce82b65411fb543d1d08342755d1efb
cpufreq: xen is default cpufreq, userspace is default governor (override on
cmdline)
Set userspace governor as default, which stays same effect
as when cpufreq in xen is not enabled. As a result, enable cpufreq
in xen by default to avoid reboot to activate cpufreq. Now it's
always on but w/o performance impact if user doesn't attempt
to change governor.
Add governor option at cmdline, add some warning info for debug.
Signed-off-by: Liu, Jinsong <jinsong.liu@xxxxxxxxx>
---
xen/arch/ia64/xen/cpufreq/cpufreq.c | 3 ++-
xen/arch/x86/acpi/cpufreq/cpufreq.c | 7 +++++--
xen/common/domain.c | 31 +++++++++++++++++++++++++------
xen/drivers/cpufreq/cpufreq.c | 16 ++++++++++++++--
xen/drivers/cpufreq/utility.c | 5 +++++
xen/include/acpi/cpufreq/cpufreq.h | 7 ++++++-
6 files changed, 57 insertions(+), 12 deletions(-)
diff -r e0301796fce8 -r 5544a96572bf xen/arch/ia64/xen/cpufreq/cpufreq.c
--- a/xen/arch/ia64/xen/cpufreq/cpufreq.c Mon Dec 29 14:05:26 2008 +0000
+++ b/xen/arch/ia64/xen/cpufreq/cpufreq.c Mon Dec 29 14:08:46 2008 +0000
@@ -226,7 +226,8 @@ acpi_cpufreq_cpu_init (struct cpufreq_po
data->acpi_data->states[i].transition_latency *
1000;
}
}
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR;
policy->cur = acpi_cpufreq_get(policy->cpu);
printk(KERN_INFO "Current freq of CPU %u is %u\n", cpu, policy->cur);
diff -r e0301796fce8 -r 5544a96572bf xen/arch/x86/acpi/cpufreq/cpufreq.c
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Mon Dec 29 14:05:26 2008 +0000
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Mon Dec 29 14:08:46 2008 +0000
@@ -393,8 +393,10 @@ static int acpi_cpufreq_target(struct cp
drv_write(&cmd);
- if (!check_freqs(cmd.mask, freqs.new, data))
+ if (!check_freqs(cmd.mask, freqs.new, data)) {
+ printk(KERN_WARNING "Fail transfer to new freq %d\n", freqs.new);
return -EAGAIN;
+ }
for_each_cpu_mask(j, online_policy_cpus)
cpufreq_statistic_update(j, perf->state, next_perf_state);
@@ -508,7 +510,8 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol
policy->cpuinfo.transition_latency =
perf->states[i].transition_latency * 1000;
}
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR;
data->max_freq = perf->states[0].core_frequency * 1000;
/* table init */
diff -r e0301796fce8 -r 5544a96572bf xen/common/domain.c
--- a/xen/common/domain.c Mon Dec 29 14:05:26 2008 +0000
+++ b/xen/common/domain.c Mon Dec 29 14:08:46 2008 +0000
@@ -33,13 +33,16 @@
/* Linux config option: propageted to domain0 */
/* xen_processor_pmbits: xen control Cx, Px, ... */
-unsigned int xen_processor_pmbits = 0;
+unsigned int xen_processor_pmbits = XEN_PROCESSOR_PM_PX;
/* opt_dom0_vcpus_pin: If true, dom0 VCPUs are pinned. */
static unsigned int opt_dom0_vcpus_pin;
boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin);
-enum cpufreq_controller cpufreq_controller;
+/* set xen as default cpufreq */
+enum cpufreq_controller cpufreq_controller = FREQCTL_xen;
+struct cpufreq_governor *cpufreq_opt_governor;
+
static void __init setup_cpufreq_option(char *str)
{
char *arg;
@@ -52,18 +55,34 @@ static void __init setup_cpufreq_option(
return;
}
+ if ( !strcmp(str, "none") )
+ {
+ xen_processor_pmbits &= ~XEN_PROCESSOR_PM_PX;
+ cpufreq_controller = FREQCTL_none;
+ return;
+ }
+
if ( (arg = strpbrk(str, ",:")) != NULL )
*arg++ = '\0';
if ( !strcmp(str, "xen") )
- {
- xen_processor_pmbits |= XEN_PROCESSOR_PM_PX;
- cpufreq_controller = FREQCTL_xen;
if ( arg && *arg )
cpufreq_cmdline_parse(arg);
- }
}
custom_param("cpufreq", setup_cpufreq_option);
+
+static void __init setup_cpufreq_gov_option(char *str)
+{
+ if ( !strcmp(str, "userspace") )
+ cpufreq_opt_governor = &cpufreq_gov_userspace;
+ else if ( !strcmp(str, "performance") )
+ cpufreq_opt_governor = &cpufreq_gov_performance;
+ else if ( !strcmp(str, "powersave") )
+ cpufreq_opt_governor = &cpufreq_gov_powersave;
+ else if ( !strcmp(str, "ondemand") )
+ cpufreq_opt_governor = &cpufreq_gov_dbs;
+}
+custom_param("cpufreq_governor", setup_cpufreq_gov_option);
/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
diff -r e0301796fce8 -r 5544a96572bf xen/drivers/cpufreq/cpufreq.c
--- a/xen/drivers/cpufreq/cpufreq.c Mon Dec 29 14:05:26 2008 +0000
+++ b/xen/drivers/cpufreq/cpufreq.c Mon Dec 29 14:08:46 2008 +0000
@@ -214,8 +214,20 @@ int cpufreq_add_cpu(unsigned int cpu)
memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
policy->governor = NULL;
ret = __cpufreq_set_policy(policy, &new_policy);
- if (ret)
- goto err2;
+ if (ret) {
+ if (new_policy.governor == CPUFREQ_DEFAULT_GOVERNOR)
+ /* if default governor fail, cpufreq really meet troubles */
+ goto err2;
+ else {
+ /* grub option governor fail */
+ /* give one more chance to default gov */
+ memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+ new_policy.governor = CPUFREQ_DEFAULT_GOVERNOR;
+ ret = __cpufreq_set_policy(policy, &new_policy);
+ if (ret)
+ goto err2;
+ }
+ }
}
return 0;
diff -r e0301796fce8 -r 5544a96572bf xen/drivers/cpufreq/utility.c
--- a/xen/drivers/cpufreq/utility.c Mon Dec 29 14:05:26 2008 +0000
+++ b/xen/drivers/cpufreq/utility.c Mon Dec 29 14:08:46 2008 +0000
@@ -360,10 +360,15 @@ int __cpufreq_set_policy(struct cpufreq_
/* start new governor */
data->governor = policy->governor;
if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
+ printk(KERN_WARNING "Fail change to %s governor\n",
+ data->governor->name);
+
/* new governor failed, so re-start old one */
if (old_gov) {
data->governor = old_gov;
__cpufreq_governor(data, CPUFREQ_GOV_START);
+ printk(KERN_WARNING "Still stay at %s governor\n",
+ data->governor->name);
}
return -EINVAL;
}
diff -r e0301796fce8 -r 5544a96572bf xen/include/acpi/cpufreq/cpufreq.h
--- a/xen/include/acpi/cpufreq/cpufreq.h Mon Dec 29 14:05:26 2008 +0000
+++ b/xen/include/acpi/cpufreq/cpufreq.h Mon Dec 29 14:08:46 2008 +0000
@@ -10,6 +10,9 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+
+#ifndef __XEN_CPUFREQ_PM_H__
+#define __XEN_CPUFREQ_PM_H__
#include <xen/types.h>
#include <xen/list.h>
@@ -85,6 +88,7 @@ struct cpufreq_governor {
struct list_head governor_list;
};
+extern struct cpufreq_governor *cpufreq_opt_governor;
extern struct cpufreq_governor cpufreq_gov_dbs;
extern struct cpufreq_governor cpufreq_gov_userspace;
extern struct cpufreq_governor cpufreq_gov_performance;
@@ -93,7 +97,7 @@ extern int cpufreq_register_governor(str
extern int cpufreq_register_governor(struct cpufreq_governor *governor);
extern int cpufreq_unregister_governor(struct cpufreq_governor *governor);
extern struct cpufreq_governor *__find_governor(const char *governor);
-#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance
+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
/* pass a target to the cpufreq driver */
extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
@@ -220,3 +224,4 @@ 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);
+#endif /* __XEN_CPUFREQ_PM_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|