diff options
Diffstat (limited to 'kernel/sched/idle.c')
| -rw-r--r-- | kernel/sched/idle.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index c47fce75e666..94b2d7b88a27 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <linux/tick.h> | 7 | #include <linux/tick.h> |
| 8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
| 9 | #include <linux/stackprotector.h> | 9 | #include <linux/stackprotector.h> |
| 10 | #include <linux/suspend.h> | ||
| 10 | 11 | ||
| 11 | #include <asm/tlb.h> | 12 | #include <asm/tlb.h> |
| 12 | 13 | ||
| @@ -47,7 +48,8 @@ static inline int cpu_idle_poll(void) | |||
| 47 | rcu_idle_enter(); | 48 | rcu_idle_enter(); |
| 48 | trace_cpu_idle_rcuidle(0, smp_processor_id()); | 49 | trace_cpu_idle_rcuidle(0, smp_processor_id()); |
| 49 | local_irq_enable(); | 50 | local_irq_enable(); |
| 50 | while (!tif_need_resched()) | 51 | while (!tif_need_resched() && |
| 52 | (cpu_idle_force_poll || tick_check_broadcast_expired())) | ||
| 51 | cpu_relax(); | 53 | cpu_relax(); |
| 52 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); | 54 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); |
| 53 | rcu_idle_exit(); | 55 | rcu_idle_exit(); |
| @@ -104,6 +106,21 @@ static void cpuidle_idle_call(void) | |||
| 104 | rcu_idle_enter(); | 106 | rcu_idle_enter(); |
| 105 | 107 | ||
| 106 | /* | 108 | /* |
| 109 | * Suspend-to-idle ("freeze") is a system state in which all user space | ||
| 110 | * has been frozen, all I/O devices have been suspended and the only | ||
| 111 | * activity happens here and in iterrupts (if any). In that case bypass | ||
| 112 | * the cpuidle governor and go stratight for the deepest idle state | ||
| 113 | * available. Possibly also suspend the local tick and the entire | ||
| 114 | * timekeeping to prevent timer interrupts from kicking us out of idle | ||
| 115 | * until a proper wakeup interrupt happens. | ||
| 116 | */ | ||
| 117 | if (idle_should_freeze()) { | ||
| 118 | cpuidle_enter_freeze(); | ||
| 119 | local_irq_enable(); | ||
| 120 | goto exit_idle; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* | ||
| 107 | * Ask the cpuidle framework to choose a convenient idle state. | 124 | * Ask the cpuidle framework to choose a convenient idle state. |
| 108 | * Fall back to the default arch idle method on errors. | 125 | * Fall back to the default arch idle method on errors. |
| 109 | */ | 126 | */ |
