cpu_idle and cpu_wait

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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!

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:

	The CPU can surely exit from the WAIT instruction by interrupt
	even if interrupts disabled?

I know the answer is yes on TX49.  Any external (or counter) interrupt
SIGNAL can break the WAIT instruction.  How about others?

---
Atsushi Nemoto


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux