summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/process.c11
-rw-r--r--arch/x86/kernel/process.c12
2 files changed, 22 insertions, 1 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 047d3e4..db4ffd0 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -199,7 +199,16 @@ void cpu_idle(void)
#ifdef CONFIG_PL310_ERRATA_769419
wmb();
#endif
- if (hlt_counter) {
+ /*
+ * In poll mode we reenable interrupts and spin.
+ *
+ * Also if we detected in the wakeup from idle
+ * path that the tick broadcast device expired
+ * for us, we don't want to go deep idle as we
+ * know that the IPI is going to arrive right
+ * away
+ */
+ if (hlt_counter || tick_check_broadcast_expired()) {
local_irq_enable();
cpu_relax();
} else if (!need_resched()) {
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 14ae100..aa524da 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -336,6 +336,18 @@ void cpu_idle(void)
local_touch_nmi();
local_irq_disable();
+ /*
+ * We detected in the wakeup path that the
+ * tick broadcast device expired for us, but
+ * we raced with the other CPU and came back
+ * here before it was able to fire the IPI.
+ * No point in going idle.
+ */
+ if (tick_check_broadcast_expired()) {
+ local_irq_enable();
+ continue;
+ }
+
enter_idle();
/* Don't trace irqs off for idle */