summaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorPuneet Saxena <puneets@nvidia.com>2013-11-13 18:48:36 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2013-11-22 01:29:49 -0800
commitfae4e3f8c163adaac322c0d7b86f8d6d9bd9dbc8 (patch)
tree6c96c18631066089054486080801b4e3066998cf /drivers/cpufreq
parentfdace94f63711465b494e802195d40cf5cb3b21c (diff)
Cpufreq: interactive: Add boost_factor
Sudden burst in load causes freq to scale hispeed_freq. This is not always good for the osidle display off use cases, where we want to scale freq conservatively. Introduces "boost_factor" which raises freq exponentially till max freq in case load remains higher than "go_hispeed_load". By default, it is DISABLED. Bug 1402227 Change-Id: I65269310ef7d2427e2ab9eb456a066571c7a9ba5 Signed-off-by: Puneet Saxena <puneets@nvidia.com> Reviewed-on: http://git-master/r/330368 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index f35d2dcdb3d3..4d6c0de2ebee 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -124,6 +124,12 @@ struct cpufreq_interactive_tunables {
int timer_slack_val;
bool io_is_busy;
+
+ /* Base of exponential raise to max speed; if 0 - jump to
+ * hispeed_freq
+ */
+#define DEFAULT_BOOST_FACTOR 0
+ unsigned int boost_factor;
};
/* For cases where we have single governor instance for system */
@@ -380,7 +386,11 @@ static void cpufreq_interactive_timer(unsigned long data)
if (cpu_load >= tunables->go_hispeed_load || boosted) {
if (pcpu->target_freq < tunables->hispeed_freq) {
- new_freq = tunables->hispeed_freq;
+ if (tunables->boost_factor)
+ new_freq = min((pcpu->target_freq
+ * tunables->boost_factor), tunables->hispeed_freq);
+ else
+ new_freq = tunables->hispeed_freq;
} else {
new_freq = choose_freq(pcpu, loadadjfreq);
@@ -814,6 +824,24 @@ static ssize_t store_hispeed_freq(struct cpufreq_interactive_tunables *tunables,
tunables->hispeed_freq = val;
return count;
}
+static ssize_t show_boost_factor(struct cpufreq_interactive_tunables *tunables,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", tunables->boost_factor);
+}
+
+static ssize_t store_boost_factor(struct cpufreq_interactive_tunables *tunables,
+ const char *buf, size_t count)
+{
+ int ret;
+ long unsigned int val;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+ tunables->boost_factor = val;
+ return count;
+}
static ssize_t show_go_hispeed_load(struct cpufreq_interactive_tunables
*tunables, char *buf)
@@ -1015,6 +1043,7 @@ store_gov_pol_sys(file_name)
show_store_gov_pol_sys(target_loads);
show_store_gov_pol_sys(above_hispeed_delay);
show_store_gov_pol_sys(hispeed_freq);
+show_store_gov_pol_sys(boost_factor);
show_store_gov_pol_sys(go_hispeed_load);
show_store_gov_pol_sys(min_sample_time);
show_store_gov_pol_sys(timer_rate);
@@ -1027,6 +1056,7 @@ show_store_gov_pol_sys(io_is_busy);
gov_sys_pol_attr_rw(target_loads);
gov_sys_pol_attr_rw(above_hispeed_delay);
gov_sys_pol_attr_rw(hispeed_freq);
+gov_sys_pol_attr_rw(boost_factor);
gov_sys_pol_attr_rw(go_hispeed_load);
gov_sys_pol_attr_rw(min_sample_time);
gov_sys_pol_attr_rw(timer_rate);
@@ -1054,6 +1084,7 @@ static struct attribute *interactive_attributes_gov_sys[] = {
&boostpulse_gov_sys.attr,
&boostpulse_duration_gov_sys.attr,
&io_is_busy_gov_sys.attr,
+ &boost_factor_gov_sys.attr,
NULL,
};
@@ -1075,6 +1106,7 @@ static struct attribute *interactive_attributes_gov_pol[] = {
&boostpulse_gov_pol.attr,
&boostpulse_duration_gov_pol.attr,
&io_is_busy_gov_pol.attr,
+ &boost_factor_gov_pol.attr,
NULL,
};
@@ -1296,6 +1328,7 @@ static int __init cpufreq_interactive_init(void)
tunables->timer_rate = DEFAULT_TIMER_RATE;
tunables->boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME;
tunables->timer_slack_val = DEFAULT_TIMER_SLACK;
+ tunables->boost_factor = DEFAULT_BOOST_FACTOR;
spin_lock_init(&tunables->target_loads_lock);
spin_lock_init(&tunables->above_hispeed_delay_lock);