[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] 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@xxxxxxxxxx>

Index: 2008-11-20/xen/common/domain.c
===================================================================
--- 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 <xen/percpu.h>
 #include <xen/multicall.h>
 #include <xen/rcupdate.h>
+#include <acpi/cpufreq/cpufreq.h>
 #include <asm/debugger.h>
 #include <public/sched.h>
 #include <public/vcpu.h>
@@ -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 &= ~XEN_PROCESSOR_PM_PX;
         cpufreq_controller = FREQCTL_dom0_kernel;
         opt_dom0_vcpus_pin = 1;
+        return;
     }
-    else if ( !strcmp(str, "xen") )
+
+    if ( (arg = strpbrk(str, ",:")) != NULL )
+        *arg++ = '\0';
+
+    if ( !strcmp(str, "xen") )
     {
         xen_processor_pmbits |= XEN_PROCESSOR_PM_PX;
         cpufreq_controller = 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
===================================================================
--- 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 <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;    /* nu
 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_
             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 );
+}
Index: 2008-11-20/xen/include/acpi/cpufreq/cpufreq.h
===================================================================
--- 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);
 
+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 */



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.