Skip to content

Commit 1c6fe03

Browse files
fenrus75torvalds
authored andcommitted
cpuidle: Fix incorrect optimization
commit 672917d ("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>
1 parent f1c448e commit 1c6fe03

File tree

1 file changed

+4
-5
lines changed
  • drivers/cpuidle/governors

1 file changed

+4
-5
lines changed

drivers/cpuidle/governors/menu.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ struct menu_device {
100100
int needs_update;
101101

102102
unsigned int expected_us;
103-
unsigned int measured_us;
104103
u64 predicted_us;
105104
unsigned int exit_us;
106105
unsigned int bucket;
@@ -187,14 +186,14 @@ static int menu_select(struct cpuidle_device *dev)
187186
int i;
188187
int multiplier;
189188

190-
data->last_state_idx = 0;
191-
data->exit_us = 0;
192-
193189
if (data->needs_update) {
194190
menu_update(dev);
195191
data->needs_update = 0;
196192
}
197193

194+
data->last_state_idx = 0;
195+
data->exit_us = 0;
196+
198197
/* Special case when user has set very strict latency requirement */
199198
if (unlikely(latency_req == 0))
200199
return 0;
@@ -294,7 +293,7 @@ static void menu_update(struct cpuidle_device *dev)
294293
new_factor = data->correction_factor[data->bucket]
295294
* (DECAY - 1) / DECAY;
296295

297-
if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING)
296+
if (data->expected_us > 0 && measured_us < MAX_INTERESTING)
298297
new_factor += RESOLUTION * measured_us / data->expected_us;
299298
else
300299
/*

0 commit comments

Comments
 (0)