From: "Jan Beulich" Subject: [PATCH] cpufreq: allow customization of some parameters Date: Fri, 05 Dec 2008 14:32:23 +0000 Message-ID: <49394987.76E4.0078.0@novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Return-path: Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org 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 Index: 2008-11-20/xen/common/domain.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 2008-11-20.orig/xen/common/domain.c 2008-10-29 15:48:38.000000000 = +0100 +++ 2008-11-20/xen/common/domain.c 2008-12-03 15:15:44.000000000 = +0100 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -41,16 +42,25 @@ boolean_param("dom0_vcpus_pin", opt_dom0 enum cpufreq_controller cpufreq_controller; static void __init setup_cpufreq_option(char *str) { + char *arg; + if ( !strcmp(str, "dom0-kernel") ) { xen_processor_pmbits &=3D ~XEN_PROCESSOR_PM_PX; cpufreq_controller =3D FREQCTL_dom0_kernel; opt_dom0_vcpus_pin =3D 1; + return; } - else if ( !strcmp(str, "xen") ) + + if ( (arg =3D strpbrk(str, ",:")) !=3D NULL ) + *arg++ =3D '\0'; + + if ( !strcmp(str, "xen") ) { xen_processor_pmbits |=3D XEN_PROCESSOR_PM_PX; cpufreq_controller =3D FREQCTL_xen; + if ( arg && *arg ) + cpufreq_cmdline_parse(arg); } } custom_param("cpufreq", setup_cpufreq_option); Index: 2008-11-20/xen/drivers/cpufreq/cpufreq_ondemand.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 2008-11-20.orig/xen/drivers/cpufreq/cpufreq_ondemand.c 2008-10-01 = 15:37:19.000000000 +0200 +++ 2008-11-20/xen/drivers/cpufreq/cpufreq_ondemand.c 2008-12-03 = 15:14:53.000000000 +0100 @@ -22,15 +22,22 @@ #include =20 #define DEF_FREQUENCY_UP_THRESHOLD (80) +#define MIN_FREQUENCY_UP_THRESHOLD (11) +#define MAX_FREQUENCY_UP_THRESHOLD (100) =20 #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 ) =20 static uint64_t def_sampling_rate; +static uint64_t usr_sampling_rate; =20 /* Sampling types */ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; @@ -42,11 +49,9 @@ static unsigned int dbs_enable; /* nu static struct dbs_tuners { uint64_t sampling_rate; unsigned int up_threshold; - unsigned int ignore_nice; unsigned int powersave_bias; } dbs_tuners_ins =3D { .up_threshold =3D DEF_FREQUENCY_UP_THRESHOLD, - .ignore_nice =3D 0, .powersave_bias =3D 0, }; =20 @@ -216,7 +221,20 @@ int cpufreq_governor_dbs(struct cpufreq_ if (def_sampling_rate < MIN_STAT_SAMPLING_RATE) def_sampling_rate =3D MIN_STAT_SAMPLING_RATE; =20 - dbs_tuners_ins.sampling_rate =3D def_sampling_rate; + if (!usr_sampling_rate) + dbs_tuners_ins.sampling_rate =3D 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 =3D 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 =3D MAX_SAMPLING_RATE; + } else + dbs_tuners_ins.sampling_rate =3D usr_sampling_rate; } dbs_timer_init(this_dbs_info); =20 @@ -244,3 +262,55 @@ struct cpufreq_governor cpufreq_gov_dbs=20 .name =3D "ondemand", .governor =3D cpufreq_governor_dbs, }; + +void __init cpufreq_cmdline_parse(char *str) +{ + do { + char *val, *end =3D strchr(str, ','); + + if ( end ) + *end++ =3D '\0'; + val =3D strchr(str, '=3D'); + if ( val ) + *val =3D '\0'; + + if ( !strcmp(str, "rate") && val ) + { + usr_sampling_rate =3D simple_strtoull(val, NULL, 0); + } + else if ( !strcmp(str, "threshold") && val ) + { + unsigned long tmp =3D 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 =3D 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 =3D MAX_FREQUENCY_UP_THRESHOLD; + } + dbs_tuners_ins.up_threshold =3D tmp; + } + else if ( !strcmp(str, "bias") && val ) + { + unsigned long tmp =3D simple_strtoul(val, NULL, 0); + + if ( tmp > 1000 ) + { + printk(XENLOG_WARNING "cpufreq/ondemand: " + "specified bias too high, using 1000\n"); + tmp =3D 1000; + } + dbs_tuners_ins.powersave_bias =3D tmp; + } + + str =3D end; + } while ( str ); +} Index: 2008-11-20/xen/include/acpi/cpufreq/cpufreq.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 2008-11-20.orig/xen/include/acpi/cpufreq/cpufreq.h 2008-10-01 = 15:37:19.000000000 +0200 +++ 2008-11-20/xen/include/acpi/cpufreq/cpufreq.h 2008-12-03 = 14:26:33.000000000 +0100 @@ -55,6 +55,8 @@ extern struct cpufreq_policy *cpufreq_cp extern int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy); =20 +void cpufreq_cmdline_parse(char *); + #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */ #define CPUFREQ_SHARED_TYPE_HW (1) /* HW does needed coordination */ #define CPUFREQ_SHARED_TYPE_ALL (2) /* All dependent CPUs should set = freq */