aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/cpufreq
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-12-05 15:23:32 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-12-05 15:23:32 +0000
commit163429c065bfc3c57416827894be3881791c94be (patch)
treef3acc2edbeb0911ef1fcdd008f59b03a4d766de3 /xen/drivers/cpufreq
parent9755643ef2560fdb81ca9d3b7b881d79a323ce0c (diff)
downloadxen-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.c80
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 );
+}