diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-12-05 15:23:32 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-12-05 15:23:32 +0000 |
commit | 163429c065bfc3c57416827894be3881791c94be (patch) | |
tree | f3acc2edbeb0911ef1fcdd008f59b03a4d766de3 /xen/drivers/cpufreq | |
parent | 9755643ef2560fdb81ca9d3b7b881d79a323ce0c (diff) | |
download | xen-163429c065bfc3c57416827894be3881791c94be.tar.gz xen-163429c065bfc3c57416827894be3881791c94be.tar.bz2 xen-163429c065bfc3c57416827894be3881791c94be.zip |
cpufreq: allow customization of some parameters
Short of having a way for powersaved to dynamically adjust these
values, at least allow specifying them on the command line. In
particular, always running at an up-threshold of 80% is perhaps nice
for laptop use, but certainly not desirable on servers. On shell
scripts invoking large numbers of short-lived processes I noticed a
50% performance degradation on a dual-socket quad-core Barcelona just
because of the load of an individual core never crossing the 80%
boundary that would have resulted in increasing the frequency.
(Powersaved on SLE10 sets this on native kernels to 60% or 80%,
depending on whether performance or power reduction is preferred,
*divided* by the number of CPUs, but capped at the lower limit of
20%.)
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/drivers/cpufreq')
-rw-r--r-- | xen/drivers/cpufreq/cpufreq_ondemand.c | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c index f1b676c2f4..d860407fca 100644 --- a/xen/drivers/cpufreq/cpufreq_ondemand.c +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c @@ -22,15 +22,22 @@ #include <acpi/cpufreq/cpufreq.h> #define DEF_FREQUENCY_UP_THRESHOLD (80) +#define MIN_FREQUENCY_UP_THRESHOLD (11) +#define MAX_FREQUENCY_UP_THRESHOLD (100) #define MIN_DBS_INTERVAL (MICROSECS(100)) -#define MIN_SAMPLING_MILLISECS (20) -#define MIN_STAT_SAMPLING_RATE \ +#define MIN_SAMPLING_RATE_RATIO (2) +#define MIN_SAMPLING_MILLISECS (MIN_SAMPLING_RATE_RATIO * 10) +#define MIN_STAT_SAMPLING_RATE \ (MIN_SAMPLING_MILLISECS * MILLISECS(1)) +#define MIN_SAMPLING_RATE \ + (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) +#define MAX_SAMPLING_RATE (500 * def_sampling_rate) #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) #define TRANSITION_LATENCY_LIMIT (10 * 1000 ) static uint64_t def_sampling_rate; +static uint64_t usr_sampling_rate; /* Sampling types */ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; @@ -42,11 +49,9 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ static struct dbs_tuners { uint64_t sampling_rate; unsigned int up_threshold; - unsigned int ignore_nice; unsigned int powersave_bias; } dbs_tuners_ins = { .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, - .ignore_nice = 0, .powersave_bias = 0, }; @@ -216,7 +221,20 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) if (def_sampling_rate < MIN_STAT_SAMPLING_RATE) def_sampling_rate = MIN_STAT_SAMPLING_RATE; - dbs_tuners_ins.sampling_rate = def_sampling_rate; + if (!usr_sampling_rate) + dbs_tuners_ins.sampling_rate = def_sampling_rate; + else if (usr_sampling_rate < MIN_SAMPLING_RATE) { + printk(KERN_WARNING "cpufreq/ondemand: " + "specified sampling rate too low, using %"PRIu64"\n", + MIN_SAMPLING_RATE); + dbs_tuners_ins.sampling_rate = MIN_SAMPLING_RATE; + } else if (usr_sampling_rate > MAX_SAMPLING_RATE) { + printk(KERN_WARNING "cpufreq/ondemand: " + "specified sampling rate too high, using %"PRIu64"\n", + MAX_SAMPLING_RATE); + dbs_tuners_ins.sampling_rate = MAX_SAMPLING_RATE; + } else + dbs_tuners_ins.sampling_rate = usr_sampling_rate; } dbs_timer_init(this_dbs_info); @@ -244,3 +262,55 @@ struct cpufreq_governor cpufreq_gov_dbs = { .name = "ondemand", .governor = cpufreq_governor_dbs, }; + +void __init cpufreq_cmdline_parse(char *str) +{ + do { + char *val, *end = strchr(str, ','); + + if ( end ) + *end++ = '\0'; + val = strchr(str, '='); + if ( val ) + *val = '\0'; + + if ( !strcmp(str, "rate") && val ) + { + usr_sampling_rate = simple_strtoull(val, NULL, 0); + } + else if ( !strcmp(str, "threshold") && val ) + { + unsigned long tmp = simple_strtoul(val, NULL, 0); + + if ( tmp < MIN_FREQUENCY_UP_THRESHOLD ) + { + printk(XENLOG_WARNING "cpufreq/ondemand: " + "specified threshold too low, using %d\n", + MIN_FREQUENCY_UP_THRESHOLD); + tmp = MIN_FREQUENCY_UP_THRESHOLD; + } + else if ( tmp > MAX_FREQUENCY_UP_THRESHOLD ) + { + printk(XENLOG_WARNING "cpufreq/ondemand: " + "specified threshold too high, using %d\n", + MAX_FREQUENCY_UP_THRESHOLD); + tmp = MAX_FREQUENCY_UP_THRESHOLD; + } + dbs_tuners_ins.up_threshold = tmp; + } + else if ( !strcmp(str, "bias") && val ) + { + unsigned long tmp = simple_strtoul(val, NULL, 0); + + if ( tmp > 1000 ) + { + printk(XENLOG_WARNING "cpufreq/ondemand: " + "specified bias too high, using 1000\n"); + tmp = 1000; + } + dbs_tuners_ins.powersave_bias = tmp; + } + + str = end; + } while ( str ); +} |