summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Renninger <trenn@suse.de>2009-04-22 13:48:29 +0200
committerDave Jones <davej@redhat.com>2009-06-15 11:49:41 -0400
commitcef9615a853ebc4972084f7e70b52892557420ac (patch)
tree9578c3371f57ab16be61e18aec307b450106106b
parent45e3e1935e2857c54783291107d33323b3ef33c8 (diff)
[CPUFREQ] ondemand: Uncouple minimal sampling rate from HZ in NO_HZ case
With this patch you have following minimal sampling rate restrictions: Kernel restrictions: If CONFIG_NO_HZ is set, the limit is 10ms fixed. If CONFIG_NO_HZ is not set or no_hz=off boot parameter is used, the limits depend on the CONFIG_HZ option: HZ=1000: min=20000us (20ms) HZ=250: min=80000us (80ms) HZ=100: min=200000us (200ms) HW restrictions: Do not sample/poll more often than HW latency * 100 exported by the low level cpufreq HW driver The higher value of above restrictions is the minimal sampling rate that can be set (and can be seen via ondemand/sampling_rate_min sysfs file) Default sampling rate still is HW latency * 1000, but this will now end up in lower values on latest (Intel and AMD) hardware as these can switch really fast and sampling rate mostly was limited to the 80ms or 200ms (depending on whether HZ=250 or HZ=1000 is used). Signed-off-by: Thomas Renninger <trenn@suse.de> Cc: Pallipadi Venkatesh <venkatesh.pallipadi@intel.com> Signed-off-by: Dave Jones <davej@redhat.com>
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c44
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c50
2 files changed, 41 insertions, 53 deletions
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 7a74d175287b..06bfe1c572cd 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -42,27 +42,12 @@
* this governor will not work.
* All times here are in uS.
*/
-static unsigned int def_sampling_rate;
#define MIN_SAMPLING_RATE_RATIO (2)
-/* for correct statistics, we need at least 10 ticks between each measure */
-#define MIN_STAT_SAMPLING_RATE \
- (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
-#define MIN_SAMPLING_RATE \
- (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
-/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
- * Define the minimal settable sampling rate to the greater of:
- * - "HW transition latency" * 100 (same as default sampling / 10)
- * - MIN_STAT_SAMPLING_RATE
- * To avoid that userspace shoots itself.
-*/
-static unsigned int minimum_sampling_rate(void)
-{
- return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
-}
-/* This will also vanish soon with removing sampling_rate_max */
-#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
+static unsigned int min_sampling_rate;
+
#define LATENCY_MULTIPLIER (1000)
+#define MIN_LATENCY_MULTIPLIER (100)
#define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (10)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
@@ -190,7 +175,7 @@ static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
current->comm);
print_once = 1;
}
- return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
+ return sprintf(buf, "%u\n", -1U);
}
static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
@@ -202,7 +187,7 @@ static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
"sysfs file is deprecated - used by: %s\n", current->comm);
print_once = 1;
}
- return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
+ return sprintf(buf, "%u\n", min_sampling_rate);
}
#define define_one_ro(_name) \
@@ -254,7 +239,7 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
return -EINVAL;
mutex_lock(&dbs_mutex);
- dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
+ dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate);
mutex_unlock(&dbs_mutex);
return count;
@@ -601,11 +586,18 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (latency == 0)
latency = 1;
- def_sampling_rate =
- max(latency * LATENCY_MULTIPLIER,
- MIN_STAT_SAMPLING_RATE);
-
- dbs_tuners_ins.sampling_rate = def_sampling_rate;
+ /*
+ * conservative does not implement micro like ondemand
+ * governor, thus we are bound to jiffes/HZ
+ */
+ min_sampling_rate =
+ MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
+ /* Bring kernel and HW constraints together */
+ min_sampling_rate = max(min_sampling_rate,
+ MIN_LATENCY_MULTIPLIER * latency);
+ dbs_tuners_ins.sampling_rate =
+ max(min_sampling_rate,
+ latency * LATENCY_MULTIPLIER);
cpufreq_register_notifier(
&dbs_cpufreq_notifier_block,
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index e741c339df76..a235114c3d85 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -32,6 +32,7 @@
#define DEF_FREQUENCY_UP_THRESHOLD (80)
#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3)
#define MICRO_FREQUENCY_UP_THRESHOLD (95)
+#define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000)
#define MIN_FREQUENCY_UP_THRESHOLD (11)
#define MAX_FREQUENCY_UP_THRESHOLD (100)
@@ -45,27 +46,12 @@
* this governor will not work.
* All times here are in uS.
*/
-static unsigned int def_sampling_rate;
#define MIN_SAMPLING_RATE_RATIO (2)
-/* for correct statistics, we need at least 10 ticks between each measure */
-#define MIN_STAT_SAMPLING_RATE \
- (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
-#define MIN_SAMPLING_RATE \
- (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
-/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
- * Define the minimal settable sampling rate to the greater of:
- * - "HW transition latency" * 100 (same as default sampling / 10)
- * - MIN_STAT_SAMPLING_RATE
- * To avoid that userspace shoots itself.
-*/
-static unsigned int minimum_sampling_rate(void)
-{
- return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
-}
-/* This will also vanish soon with removing sampling_rate_max */
-#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
+static unsigned int min_sampling_rate;
+
#define LATENCY_MULTIPLIER (1000)
+#define MIN_LATENCY_MULTIPLIER (100)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
static void do_dbs_timer(struct work_struct *work);
@@ -227,7 +213,7 @@ static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
current->comm);
print_once = 1;
}
- return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
+ return sprintf(buf, "%u\n", -1U);
}
static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
@@ -240,7 +226,7 @@ static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
current->comm);
print_once = 1;
}
- return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
+ return sprintf(buf, "%u\n", min_sampling_rate);
}
#define define_one_ro(_name) \
@@ -274,7 +260,7 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
mutex_unlock(&dbs_mutex);
return -EINVAL;
}
- dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
+ dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate);
mutex_unlock(&dbs_mutex);
return count;
@@ -619,12 +605,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
latency = policy->cpuinfo.transition_latency / 1000;
if (latency == 0)
latency = 1;
-
- def_sampling_rate =
- max(latency * LATENCY_MULTIPLIER,
- MIN_STAT_SAMPLING_RATE);
-
- dbs_tuners_ins.sampling_rate = def_sampling_rate;
+ /* Bring kernel and HW constraints together */
+ min_sampling_rate = max(min_sampling_rate,
+ MIN_LATENCY_MULTIPLIER * latency);
+ dbs_tuners_ins.sampling_rate =
+ max(min_sampling_rate,
+ latency * LATENCY_MULTIPLIER);
}
dbs_timer_init(this_dbs_info);
@@ -678,6 +664,16 @@ static int __init cpufreq_gov_dbs_init(void)
dbs_tuners_ins.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
dbs_tuners_ins.down_differential =
MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
+ /*
+ * In no_hz/micro accounting case we set the minimum frequency
+ * not depending on HZ, but fixed (very low). The deferred
+ * timer might skip some samples if idle/sleeping as needed.
+ */
+ min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
+ } else {
+ /* For correct statistics, we need 10 ticks for each measure */
+ min_sampling_rate =
+ MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
}
kondemand_wq = create_workqueue("kondemand");