Commit 0b89e9aa authored by Paul Burton's avatar Paul Burton Committed by Rafael J. Wysocki

cpuidle: delay enabling interrupts until all coupled CPUs leave idle

As described by a comment at the end of cpuidle_enter_state_coupled it
can be inefficient for coupled idle states to return with IRQs enabled
since they may proceed to service an interrupt instead of clearing the
coupled idle state. Until they have finished & cleared the idle state
all CPUs coupled with them will spin rather than being able to enter a
safe idle state.

Commits e1689795 "cpuidle: Add common time keeping and irq
enabling" and 554c06ba "cpuidle: remove en_core_tk_irqen flag" led
to the cpuidle_enter_state enabling interrupts for all idle states,
including coupled ones, making this inefficiency unavoidable by drivers
& the local_irq_enable near the end of cpuidle_enter_state_coupled
redundant. This patch avoids enabling interrupts in cpuidle_enter_state
after a coupled state has been entered, allowing them to remain disabled
until all coupled CPUs have exited the idle state and
cpuidle_enter_state_coupled re-enables them.

Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 4b2f0b03
...@@ -85,6 +85,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, ...@@ -85,6 +85,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
time_end = ktime_get(); time_end = ktime_get();
if (!cpuidle_state_is_coupled(dev, drv, entered_state))
local_irq_enable(); local_irq_enable();
diff = ktime_to_us(ktime_sub(time_end, time_start)); diff = ktime_to_us(ktime_sub(time_end, time_start));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment