From: Keir Fraser Date: Mon, 29 Dec 2008 14:08:46 +0000 (+0000) Subject: cpufreq: xen is default cpufreq, userspace is default governor (override on cmdline) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14019^2~28 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=119a6a6e07a5b5d41b87ce8a0886761db40325b8;p=xen.git 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 --- diff --git a/xen/arch/ia64/xen/cpufreq/cpufreq.c b/xen/arch/ia64/xen/cpufreq/cpufreq.c index c2c311ddea..fdd6888108 100644 --- a/xen/arch/ia64/xen/cpufreq/cpufreq.c +++ b/xen/arch/ia64/xen/cpufreq/cpufreq.c @@ -226,7 +226,8 @@ acpi_cpufreq_cpu_init (struct cpufreq_policy *policy) 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 --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c index 8ddd274a20..4a6f0abf7b 100644 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c @@ -393,8 +393,10 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, 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_policy *policy) 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 --git a/xen/common/domain.c b/xen/common/domain.c index e94740675e..ab807bfbf8 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -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,19 +55,35 @@ static void __init setup_cpufreq_option(char *str) 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); DEFINE_RCU_READ_LOCK(domlist_read_lock); diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c index 169426e373..dee38fa513 100644 --- a/xen/drivers/cpufreq/cpufreq.c +++ b/xen/drivers/cpufreq/cpufreq.c @@ -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 --git a/xen/drivers/cpufreq/utility.c b/xen/drivers/cpufreq/utility.c index 1c8176fabe..4ac3833923 100644 --- a/xen/drivers/cpufreq/utility.c +++ b/xen/drivers/cpufreq/utility.c @@ -360,10 +360,15 @@ int __cpufreq_set_policy(struct cpufreq_policy *data, /* 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 --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h index 20441ff934..4314414031 100644 --- a/xen/include/acpi/cpufreq/cpufreq.h +++ b/xen/include/acpi/cpufreq/cpufreq.h @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +#ifndef __XEN_CPUFREQ_PM_H__ +#define __XEN_CPUFREQ_PM_H__ + #include #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 struct cpufreq_governor cpufreq_gov_powersave; 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 *sampling_rate_max, 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__ */