Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cpuidle: Fix incorrect optimization

commit 672917dcc78 ("cpuidle: menu governor: reduce latency on exit")
added an optimization, where the analysis on the past idle period moved
from the end of idle, to the beginning of the new idle.

Unfortunately, this optimization had a bug where it zeroed one key
variable for new use, that is needed for the analysis. The fix is
simple, zero the variable after doing the work from the previous idle.

During the audit of the code that found this issue, another issue was
also found; the ->measured_us data structure member is never set, a
local variable is always used instead.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Corrado Zoccolo <czoccolo@gmail.com>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Arjan van de Ven and committed by
Linus Torvalds
1c6fe036 f1c448e0

+4 -5
+4 -5
drivers/cpuidle/governors/menu.c
··· 100 100 int needs_update; 101 101 102 102 unsigned int expected_us; 103 - unsigned int measured_us; 104 103 u64 predicted_us; 105 104 unsigned int exit_us; 106 105 unsigned int bucket; ··· 186 187 int i; 187 188 int multiplier; 188 189 189 - data->last_state_idx = 0; 190 - data->exit_us = 0; 191 - 192 190 if (data->needs_update) { 193 191 menu_update(dev); 194 192 data->needs_update = 0; 195 193 } 194 + 195 + data->last_state_idx = 0; 196 + data->exit_us = 0; 196 197 197 198 /* Special case when user has set very strict latency requirement */ 198 199 if (unlikely(latency_req == 0)) ··· 293 294 new_factor = data->correction_factor[data->bucket] 294 295 * (DECAY - 1) / DECAY; 295 296 296 - if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING) 297 + if (data->expected_us > 0 && measured_us < MAX_INTERESTING) 297 298 new_factor += RESOLUTION * measured_us / data->expected_us; 298 299 else 299 300 /*