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

Merge branch 'pm-cpuidle'

* pm-cpuidle:
cpuidle: powernv/pseries: Auto-promotion of snooze to deeper idle state

+23
+12
drivers/cpuidle/cpuidle-powernv.c
··· 29 29 30 30 static int max_idle_state; 31 31 static struct cpuidle_state *cpuidle_state_table; 32 + static u64 snooze_timeout; 33 + static bool snooze_timeout_en; 32 34 33 35 static int snooze_loop(struct cpuidle_device *dev, 34 36 struct cpuidle_driver *drv, 35 37 int index) 36 38 { 39 + u64 snooze_exit_time; 40 + 37 41 local_irq_enable(); 38 42 set_thread_flag(TIF_POLLING_NRFLAG); 39 43 44 + snooze_exit_time = get_tb() + snooze_timeout; 40 45 ppc64_runlatch_off(); 41 46 while (!need_resched()) { 42 47 HMT_low(); 43 48 HMT_very_low(); 49 + if (snooze_timeout_en && get_tb() > snooze_exit_time) 50 + break; 44 51 } 45 52 46 53 HMT_medium(); ··· 259 252 cpuidle_state_table = powernv_states; 260 253 /* Device tree can indicate more idle states */ 261 254 max_idle_state = powernv_add_idle_states(); 255 + if (max_idle_state > 1) { 256 + snooze_timeout_en = true; 257 + snooze_timeout = powernv_states[1].target_residency * 258 + tb_ticks_per_usec; 259 + } 262 260 } else 263 261 return -ENODEV; 264 262
+11
drivers/cpuidle/cpuidle-pseries.c
··· 27 27 28 28 static int max_idle_state; 29 29 static struct cpuidle_state *cpuidle_state_table; 30 + static u64 snooze_timeout; 31 + static bool snooze_timeout_en; 30 32 31 33 static inline void idle_loop_prolog(unsigned long *in_purr) 32 34 { ··· 60 58 int index) 61 59 { 62 60 unsigned long in_purr; 61 + u64 snooze_exit_time; 63 62 64 63 idle_loop_prolog(&in_purr); 65 64 local_irq_enable(); 66 65 set_thread_flag(TIF_POLLING_NRFLAG); 66 + snooze_exit_time = get_tb() + snooze_timeout; 67 67 68 68 while (!need_resched()) { 69 69 HMT_low(); 70 70 HMT_very_low(); 71 + if (snooze_timeout_en && get_tb() > snooze_exit_time) 72 + break; 71 73 } 72 74 73 75 HMT_medium(); ··· 250 244 } else 251 245 return -ENODEV; 252 246 247 + if (max_idle_state > 1) { 248 + snooze_timeout_en = true; 249 + snooze_timeout = cpuidle_state_table[1].target_residency * 250 + tb_ticks_per_usec; 251 + } 253 252 return 0; 254 253 } 255 254