diff options
| -rw-r--r-- | kernel/sched/idle.c | 78 |
1 files changed, 44 insertions, 34 deletions
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index dc8a2466418f..cc7a6f3801ff 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c | |||
| @@ -76,44 +76,59 @@ static int cpuidle_idle_call(void) | |||
| 76 | int next_state, entered_state, ret; | 76 | int next_state, entered_state, ret; |
| 77 | bool broadcast; | 77 | bool broadcast; |
| 78 | 78 | ||
| 79 | if (current_clr_polling_and_test()) { | ||
| 80 | local_irq_enable(); | ||
| 81 | __current_set_polling(); | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 79 | stop_critical_timings(); | 85 | stop_critical_timings(); |
| 80 | rcu_idle_enter(); | 86 | rcu_idle_enter(); |
| 81 | 87 | ||
| 82 | ret = cpuidle_enabled(drv, dev); | 88 | ret = cpuidle_enabled(drv, dev); |
| 83 | if (ret < 0) { | ||
| 84 | arch_cpu_idle(); | ||
| 85 | goto out; | ||
| 86 | } | ||
| 87 | 89 | ||
| 88 | /* ask the governor for the next state */ | 90 | if (!ret) { |
| 89 | next_state = cpuidle_select(drv, dev); | 91 | /* ask the governor for the next state */ |
| 92 | next_state = cpuidle_select(drv, dev); | ||
| 90 | 93 | ||
| 91 | if (need_resched()) { | 94 | if (current_clr_polling_and_test()) { |
| 92 | dev->last_residency = 0; | 95 | dev->last_residency = 0; |
| 93 | /* give the governor an opportunity to reflect on the outcome */ | 96 | entered_state = next_state; |
| 94 | cpuidle_reflect(dev, next_state); | 97 | local_irq_enable(); |
| 95 | local_irq_enable(); | 98 | } else { |
| 96 | goto out; | 99 | broadcast = !!(drv->states[next_state].flags & |
| 97 | } | 100 | CPUIDLE_FLAG_TIMER_STOP); |
| 101 | |||
| 102 | if (broadcast) | ||
| 103 | ret = clockevents_notify( | ||
| 104 | CLOCK_EVT_NOTIFY_BROADCAST_ENTER, | ||
| 105 | &dev->cpu); | ||
| 98 | 106 | ||
| 99 | broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP); | 107 | if (!ret) { |
| 108 | trace_cpu_idle_rcuidle(next_state, dev->cpu); | ||
| 100 | 109 | ||
| 101 | if (broadcast && | 110 | entered_state = cpuidle_enter(drv, dev, |
| 102 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu)) | 111 | next_state); |
| 103 | return -EBUSY; | ||
| 104 | 112 | ||
| 105 | trace_cpu_idle_rcuidle(next_state, dev->cpu); | 113 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, |
| 114 | dev->cpu); | ||
| 106 | 115 | ||
| 107 | entered_state = cpuidle_enter(drv, dev, next_state); | 116 | if (broadcast) |
| 117 | clockevents_notify( | ||
| 118 | CLOCK_EVT_NOTIFY_BROADCAST_EXIT, | ||
| 119 | &dev->cpu); | ||
| 108 | 120 | ||
| 109 | trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); | 121 | /* give the governor an opportunity to reflect on the outcome */ |
| 122 | cpuidle_reflect(dev, entered_state); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | if (ret) | ||
| 128 | arch_cpu_idle(); | ||
| 110 | 129 | ||
| 111 | if (broadcast) | 130 | __current_set_polling(); |
| 112 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); | ||
| 113 | 131 | ||
| 114 | /* give the governor an opportunity to reflect on the outcome */ | ||
| 115 | cpuidle_reflect(dev, entered_state); | ||
| 116 | out: | ||
| 117 | if (WARN_ON_ONCE(irqs_disabled())) | 132 | if (WARN_ON_ONCE(irqs_disabled())) |
| 118 | local_irq_enable(); | 133 | local_irq_enable(); |
| 119 | 134 | ||
| @@ -150,16 +165,11 @@ static void cpu_idle_loop(void) | |||
| 150 | * know that the IPI is going to arrive right | 165 | * know that the IPI is going to arrive right |
| 151 | * away | 166 | * away |
| 152 | */ | 167 | */ |
| 153 | if (cpu_idle_force_poll || tick_check_broadcast_expired()) { | 168 | if (cpu_idle_force_poll || tick_check_broadcast_expired()) |
| 154 | cpu_idle_poll(); | 169 | cpu_idle_poll(); |
| 155 | } else { | 170 | else |
| 156 | if (!current_clr_polling_and_test()) { | 171 | cpuidle_idle_call(); |
| 157 | cpuidle_idle_call(); | 172 | |
| 158 | } else { | ||
| 159 | local_irq_enable(); | ||
| 160 | } | ||
| 161 | __current_set_polling(); | ||
| 162 | } | ||
| 163 | arch_cpu_idle_exit(); | 173 | arch_cpu_idle_exit(); |
| 164 | } | 174 | } |
| 165 | 175 | ||
