Mailing List Archive

[PATCH] misc cpufreq cleanup
- 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 <jbeulich@novell.com>

--- 2011-04-29.orig/xen/drivers/cpufreq/cpufreq.c
+++ 2011-04-29/xen/drivers/cpufreq/cpufreq.c
@@ -47,7 +47,8 @@
#include <acpi/acpi.h>
#include <acpi/cpufreq/cpufreq.h>

-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 <xen/cpu.h>
#include <xen/init.h>
+#include <xen/percpu.h>
#include <xen/sched.h>
#include <acpi/cpufreq/cpufreq.h>

/*
* 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;
};