cpufreq: interactive: fix to come out of hysteresis mode

If policy max is set to less than or equal to hispeed_freq, governor can
get stuck in hysteresis mode as long as cpufreq_interactive_timer keeps
coming with in hysteresis period (max_freq_hysteresis). This is because
governor updates hysteresis start time (max_freq_hyst_start_time)
everytime new frequency is greater than or equal to policy max and
jump_to_max_no_ts flag is false. Irrespective of load new frequency in
this case will always end up at least at hispeed_freq due to hysteresis.
As policy max is set to less than or equal to hispeed_freq, this will
result in updating max_freq_hyst_start_time if jump_to_max_no_ts is
false. This will end up restarting hysteresis period. This mode will
break only if timer gets delivered after hysteresis period. Otherwise it
keeps extending.

To come out of this, don't update max_freq_hyst_start_time if new
frequency is bumped up to hispeed_freq due to hysteresis even though the
required frequency as per load is less than policy max and hispeed_freq.

Change-Id: Ib1e9e612036afeb12acd86e603b019e227920d85
Signed-off-by: Ramakrishna Gottimukkula <rgottimu@codeaurora.org>
This commit is contained in:
Ramakrishna Gottimukkula 2017-07-26 23:33:28 +05:30
parent ac8211566b
commit 168e1040e7

View file

@ -479,6 +479,7 @@ static void cpufreq_interactive_timer(unsigned long data)
bool skip_hispeed_logic, skip_min_sample_time;
bool jump_to_max_no_ts = false;
bool jump_to_max = false;
bool start_hyst = true;
if (!down_read_trylock(&ppol->enable_sem))
return;
@ -588,8 +589,12 @@ static void cpufreq_interactive_timer(unsigned long data)
}
if (now - ppol->max_freq_hyst_start_time <
tunables->max_freq_hysteresis)
tunables->max_freq_hysteresis) {
if (new_freq < ppol->policy->max &&
ppol->policy->max <= tunables->hispeed_freq)
start_hyst = false;
new_freq = max(tunables->hispeed_freq, new_freq);
}
if (!skip_hispeed_logic &&
ppol->target_freq >= tunables->hispeed_freq &&
@ -646,7 +651,7 @@ static void cpufreq_interactive_timer(unsigned long data)
ppol->floor_validate_time = now;
}
if (new_freq >= ppol->policy->max && !jump_to_max_no_ts)
if (start_hyst && new_freq >= ppol->policy->max && !jump_to_max_no_ts)
ppol->max_freq_hyst_start_time = now;
if (ppol->target_freq == new_freq &&