Set xen as default cpufreq, set userspace as default governor, add governor option at 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 tempt to change governor. Add governor option at cmdline, add some warning info for debug. Signed-off-by: Liu, Jinsong diff -r cf1af684132c xen/arch/ia64/xen/cpufreq/cpufreq.c --- a/xen/arch/ia64/xen/cpufreq/cpufreq.c Wed Dec 24 09:14:56 2008 +0800 +++ b/xen/arch/ia64/xen/cpufreq/cpufreq.c Fri Dec 26 10:36:27 2008 +0800 @@ -226,7 +226,9 @@ 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_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 cf1af684132c xen/arch/x86/acpi/cpufreq/cpufreq.c --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Wed Dec 24 09:14:56 2008 +0800 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Fri Dec 26 10:36:27 2008 +0800 @@ -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,9 @@ 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_opt_governor : CPUFREQ_DEFAULT_GOVERNOR; data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ diff -r cf1af684132c xen/common/domain.c --- a/xen/common/domain.c Wed Dec 24 09:14:56 2008 +0800 +++ b/xen/common/domain.c Fri Dec 26 10:36:27 2008 +0800 @@ -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 cf1af684132c xen/drivers/cpufreq/cpufreq.c --- a/xen/drivers/cpufreq/cpufreq.c Wed Dec 24 09:14:56 2008 +0800 +++ b/xen/drivers/cpufreq/cpufreq.c Fri Dec 26 10:36:27 2008 +0800 @@ -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 cf1af684132c xen/drivers/cpufreq/utility.c --- a/xen/drivers/cpufreq/utility.c Wed Dec 24 09:14:56 2008 +0800 +++ b/xen/drivers/cpufreq/utility.c Fri Dec 26 10:36:27 2008 +0800 @@ -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 cf1af684132c xen/include/acpi/cpufreq/cpufreq.h --- a/xen/include/acpi/cpufreq/cpufreq.h Wed Dec 24 09:14:56 2008 +0800 +++ b/xen/include/acpi/cpufreq/cpufreq.h Fri Dec 26 10:36:27 2008 +0800 @@ -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 #include @@ -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__ */