Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need to disable interrupt before WFI in ARM Linux cpu_idle

The Linux kernel for ARM basically does CPU_idle in a loop:

while (1) {
    disalbe_irq
    wfi
    enable_irq
}

I can understand that this logic works because "wfi" wakes up ARM regardless of IRQ/FIQ status. However, why "wfi" has to be bracketed by disable_irq and eanble_irq in the first place?

The source code /arch/arm/process.c has the following commends:

* We need to disable interrupts here
* to ensure we don't miss a wakeup call.

But I can't make sense of it. Can someone enlighten me in which scenario we would miss a wakeup call ?

like image 795
Joey Avatar asked Apr 26 '14 02:04

Joey


People also ask

Why would you disable interrupts?

If an interrupt comes in in-between any of those instructions and modifies the data, your first ISR can potentially read the wrong value. So you need to disable interrupts before you operate on it and also declare the variable volatile .

What is the reason for disabling interrupts when operating in certain code segments?

Interrupts and Pipelined CodeBecause an interrupt in the middle of a fully primed pipe destroys the synergy in instruction execution, the compiler may protect a software pipelining operation by disabling interrupts before entering the pipelined section and enabling interrupts on the way out (Figure 6.34).

What happens if interrupts are disabled?

"In a multithreaded system , if you disable interrupts, that means timer interrupts are also disabled.. and then a scheduler works on a timer only... so if the timer interrupt is disabled, it will not expire the scheduler and it will not find any task to schedule... and then again if interrupts are disabled, then no ...

Which instruction is used to disable interrupts?

The "di instruction" and "ei instruction" of the assembler instruction can be used to disable an interrupt locally in a function described in C language.


1 Answers

The whole 'going to sleep' sequence in the main loop is split into two steps:

  1. Realize that you don't have work to do;
  2. Try to sleep (i.e. WFI)

The WFI instruction will act as a NOP if there are some interrupt flags still set, which allows the main loop to go back running the required tasks. So far so good.

There's a problem though if an interrupt occurs right after step 1 and before step 2. If that happens then the interrupt flags will be cleared upon exiting the ISR, and when control goes back to the main loop it will hit the WFI instruction with all interrupt flags cleared, causing the CPU to go into sleep before the main loop has had a chance to execute whatever tasks were required by the ISR.

like image 110
AlfredD Avatar answered Oct 24 '22 10:10

AlfredD