aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq_ondemand.c
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 /drivers/cpufreq/cpufreq_ondemand.c
parent45e3e1935e2857c54783291107d33323b3ef33c8 (diff)
downloadkernel_samsung_smdk4412-cef9615a853ebc4972084f7e70b52892557420ac.zip
kernel_samsung_smdk4412-cef9615a853ebc4972084f7e70b52892557420ac.tar.gz
kernel_samsung_smdk4412-cef9615a853ebc4972084f7e70b52892557420ac.tar.bz2
[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>
Diffstat (limited to 'drivers/cpufreq/cpufreq_ondemand.c')
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c50
1 files changed, 23 insertions, 27 deletions
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index e741c33..a235114 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");