On Thu, Nov 17, 2005 at 01:19:06AM +0900, Atsushi Nemoto wrote: > Looking at recent change in cpu_idle(), I find an another potential > problem with cpu_wait (WAIT instruction). > > 48 ATTRIB_NORET void cpu_idle(void) > 49 { > 50 /* endless idle loop with no priority at all */ > 51 while (1) { > 52 while (!need_resched()) > 53 if (cpu_wait) > 54 (*cpu_wait)(); > 55 preempt_enable_no_resched(); > 56 schedule(); > 57 preempt_disable(); > 58 } > 59 } > > If an interrupt raised on line 53 and the interrupt handler woke a > sleeping thread up, the thread becomes runnable and current thread > (idle thread) is marked as NEED_RESCHED. > > Since preemption is disabled, the interrupt handler just return to > current thread (idle thread) without rescheduling. The idle thread > then call cpu_wait() and execute WAIT instruction (or something > similer). The CPU will stops until next interrupt. Then the idle > task checks need_resched() and finally calls schedule(). Therefore, > wakeup-resume latency will be nearly one TICK on worst case! Pleassure. > If this analysis was correct, how to fix this? > > Removing above preempt_enable_no_resched/preempt_disable pair would > fix it for preemptive kernel, but no point for non-preemptive kernel. > Replacing them with local_irq_enable/local_irq_disable would fix it > for both kernel, but there is an question: Somebody sneaking those lines into kernel.org ... > The CPU can surely exit from the WAIT instruction by interrupt > even if interrupts disabled? That's implementation dependent behaviour, unfortunately. Ralf