diff options
Diffstat (limited to 'drivers/cpuidle/governors/menu.c')
-rw-r--r-- | drivers/cpuidle/governors/menu.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index f508690eb95..f9c6ca7b937 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -19,6 +19,8 @@ #include <linux/tick.h> #include <linux/sched.h> #include <linux/math64.h> +#include <linux/cpu.h> +#include <linux/sysfs.h> #define BUCKETS 12 #define INTERVALS 8 @@ -121,6 +123,7 @@ struct menu_device { int interval_ptr; }; +static int tune_multiplier = 1024; #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) @@ -170,6 +173,9 @@ static inline int performance_multiplier(void) { int mult = 1; + if (tune_multiplier <= 1) + return tune_multiplier; + /* for higher loadavg, we are more reluctant */ mult += 2 * get_loadavg(); @@ -177,6 +183,9 @@ static inline int performance_multiplier(void) /* for IO wait tasks (per cpu!) we add 5x each */ mult += 10 * nr_iowait_cpu(smp_processor_id()); + if (tune_multiplier != 1024) + mult = (tune_multiplier * mult) / 1024; + return mult; } @@ -379,6 +388,54 @@ static void menu_update(struct cpuidle_device *dev) data->interval_ptr = 0; } +int cpuidle_set_multiplier(unsigned int value) +{ + + if (value > 1024) + tune_multiplier = 1024; + else + tune_multiplier = value; + + return 0; +} +EXPORT_SYMBOL(cpuidle_set_multiplier); + +static ssize_t show_multiplier(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", tune_multiplier); +} + +static ssize_t store_multiplier(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + ret = sscanf(buf, "%u", &input); + + if (ret != 1) + return -EINVAL; + + cpuidle_set_multiplier(input); + + return count; +} + + +static SYSDEV_CLASS_ATTR(multiplier, 0644, show_multiplier, store_multiplier); + +static struct attribute *dbs_attributes[] = { + &attr_multiplier.attr, + NULL +}; + +static struct attribute_group dbs_attr_group = { + .attrs = dbs_attributes, + .name = "cpuidle", +}; + /** * menu_enable_device - scans a CPU's states and does setup * @dev: the CPU @@ -406,7 +463,15 @@ static struct cpuidle_governor menu_governor = { */ static int __init init_menu(void) { - return cpuidle_register_governor(&menu_governor); + int ret; + + ret = cpuidle_register_governor(&menu_governor); + + sysfs_merge_group(&(cpu_sysdev_class.kset.kobj), + &dbs_attr_group); + + return ret; + } /** @@ -414,6 +479,9 @@ static int __init init_menu(void) */ static void __exit exit_menu(void) { + sysfs_unmerge_group(&(cpu_sysdev_class.kset.kobj), + &dbs_attr_group); + cpuidle_unregister_governor(&menu_governor); } |