|
@@ -71,13 +71,20 @@ static int snooze_loop(struct cpuidle_device *dev,
|
|
|
while (!need_resched()) {
|
|
|
HMT_low();
|
|
|
HMT_very_low();
|
|
|
- if (snooze_timeout_en && get_tb() > snooze_exit_time)
|
|
|
+ if (likely(snooze_timeout_en) && get_tb() > snooze_exit_time) {
|
|
|
+ /*
|
|
|
+ * Task has not woken up but we are exiting the polling
|
|
|
+ * loop anyway. Require a barrier after polling is
|
|
|
+ * cleared to order subsequent test of need_resched().
|
|
|
+ */
|
|
|
+ clear_thread_flag(TIF_POLLING_NRFLAG);
|
|
|
+ smp_mb();
|
|
|
break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
HMT_medium();
|
|
|
clear_thread_flag(TIF_POLLING_NRFLAG);
|
|
|
- smp_mb();
|
|
|
|
|
|
idle_loop_epilog(in_purr);
|
|
|
|