- proper handling of governor command line options when using the default governor - warning message for unrecognized command line options - replacing a NR_CPUS sized array with per-CPU data - a couple of __read_mostly annotations Signed-off-by: Jan Beulich --- 2011-04-29.orig/xen/drivers/cpufreq/cpufreq.c +++ 2011-04-29/xen/drivers/cpufreq/cpufreq.c @@ -47,7 +47,8 @@ #include #include -static unsigned int usr_max_freq, usr_min_freq; +static unsigned int __read_mostly usr_min_freq; +static unsigned int __read_mostly usr_max_freq; static void cpufreq_cmdline_common_para(struct cpufreq_policy *new_policy); struct cpufreq_dom { @@ -55,10 +56,10 @@ struct cpufreq_dom { cpumask_t map; struct list_head node; }; -static LIST_HEAD(cpufreq_dom_list_head); +static LIST_HEAD_READ_MOSTLY(cpufreq_dom_list_head); -struct cpufreq_governor *cpufreq_opt_governor; -LIST_HEAD(cpufreq_governor_list); +struct cpufreq_governor *__read_mostly cpufreq_opt_governor; +LIST_HEAD_READ_MOSTLY(cpufreq_governor_list); bool_t __read_mostly cpufreq_verbose; @@ -525,6 +526,7 @@ void __init cpufreq_cmdline_parse(char * { static struct cpufreq_governor *__initdata cpufreq_governors[] = { + CPUFREQ_DEFAULT_GOVERNOR, &cpufreq_gov_userspace, &cpufreq_gov_dbs, &cpufreq_gov_performance, @@ -558,8 +560,10 @@ void __init cpufreq_cmdline_parse(char * } if (str && !cpufreq_handle_common_option(str, val) && - cpufreq_governors[gov_index]->handle_option) - cpufreq_governors[gov_index]->handle_option(str, val); + (!cpufreq_governors[gov_index]->handle_option || + !cpufreq_governors[gov_index]->handle_option(str, val))) + printk(XENLOG_WARNING "cpufreq/%s: option '%s' not recognized\n", + cpufreq_governors[gov_index]->name, str); str = end; } while (str); --- 2011-04-29.orig/xen/drivers/cpufreq/cpufreq_misc_governors.c +++ 2011-04-29/xen/drivers/cpufreq/cpufreq_misc_governors.c @@ -14,14 +14,17 @@ * */ +#include #include +#include #include #include /* * cpufreq userspace governor */ -static unsigned int cpu_set_freq[NR_CPUS]; +static unsigned int __read_mostly userspace_cmdline_freq; +static DEFINE_PER_CPU(unsigned int, cpu_set_freq); static int cpufreq_governor_userspace(struct cpufreq_policy *policy, unsigned int event) @@ -35,21 +38,21 @@ static int cpufreq_governor_userspace(st switch (event) { case CPUFREQ_GOV_START: - if (!cpu_set_freq[cpu]) - cpu_set_freq[cpu] = policy->cur; + if (!per_cpu(cpu_set_freq, cpu)) + per_cpu(cpu_set_freq, cpu) = policy->cur; break; case CPUFREQ_GOV_STOP: - cpu_set_freq[cpu] = 0; + per_cpu(cpu_set_freq, cpu) = 0; break; case CPUFREQ_GOV_LIMITS: - if (policy->max < cpu_set_freq[cpu]) + if (policy->max < per_cpu(cpu_set_freq, cpu)) ret = __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - else if (policy->min > cpu_set_freq[cpu]) + else if (policy->min > per_cpu(cpu_set_freq, cpu)) ret = __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); else - ret = __cpufreq_driver_target(policy, cpu_set_freq[cpu], + ret = __cpufreq_driver_target(policy, per_cpu(cpu_set_freq, cpu), CPUFREQ_RELATION_L); break; @@ -68,7 +71,7 @@ int write_userspace_scaling_setspeed(uns if (!cpu_online(cpu) || !(policy = per_cpu(cpufreq_cpu_policy, cpu))) return -EINVAL; - cpu_set_freq[cpu] = freq; + per_cpu(cpu_set_freq, cpu) = freq; if (freq < policy->min) freq = policy->min; @@ -78,19 +81,35 @@ int write_userspace_scaling_setspeed(uns return __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); } -static void __init +static bool_t __init cpufreq_userspace_handle_option(const char *name, const char *val) { if (!strcmp(name, "speed") && val) { - unsigned int usr_cmdline_freq; - unsigned int cpu; + userspace_cmdline_freq = simple_strtoul(val, NULL, 0); + return 1; + } + return 0; +} - usr_cmdline_freq = simple_strtoul(val, NULL, 0); - for (cpu = 0; cpu < NR_CPUS; cpu++) - cpu_set_freq[cpu] = usr_cmdline_freq; +static int cpufreq_userspace_cpu_callback( + struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + + switch (action) + { + case CPU_UP_PREPARE: + per_cpu(cpu_set_freq, cpu) = userspace_cmdline_freq; + break; } + + return NOTIFY_DONE; } +static struct notifier_block cpufreq_userspace_cpu_nfb = { + .notifier_call = cpufreq_userspace_cpu_callback +}; + struct cpufreq_governor cpufreq_gov_userspace = { .name = "userspace", .governor = cpufreq_governor_userspace, @@ -99,6 +118,11 @@ struct cpufreq_governor cpufreq_gov_user static int __init cpufreq_gov_userspace_init(void) { + unsigned int cpu; + + for_each_online_cpu(cpu) + per_cpu(cpu_set_freq, cpu) = userspace_cmdline_freq; + register_cpu_notifier(&cpufreq_userspace_cpu_nfb); return cpufreq_register_governor(&cpufreq_gov_userspace); } __initcall(cpufreq_gov_userspace_init); --- 2011-04-29.orig/xen/drivers/cpufreq/cpufreq_ondemand.c +++ 2011-04-29/xen/drivers/cpufreq/cpufreq_ondemand.c @@ -296,7 +296,7 @@ int cpufreq_governor_dbs(struct cpufreq_ return 0; } -static void __init cpufreq_dbs_handle_option(const char *name, const char *val) +static bool_t __init cpufreq_dbs_handle_option(const char *name, const char *val) { if ( !strcmp(name, "rate") && val ) { @@ -334,6 +334,9 @@ static void __init cpufreq_dbs_handle_op } dbs_tuners_ins.powersave_bias = tmp; } + else + return 0; + return 1; } struct cpufreq_governor cpufreq_gov_dbs = { --- 2011-04-29.orig/xen/include/acpi/cpufreq/cpufreq.h +++ 2011-04-29/xen/include/acpi/cpufreq/cpufreq.h @@ -93,7 +93,7 @@ struct cpufreq_governor { char name[CPUFREQ_NAME_LEN]; int (*governor)(struct cpufreq_policy *policy, unsigned int event); - void (*handle_option)(const char *name, const char *value); + bool_t (*handle_option)(const char *name, const char *value); struct list_head governor_list; };