Can an interrupt handler be preempted by the same interrupt handler?
Asked Answered
F

5

7

Does the CPU disable all interrupts on local CPU before calling the interrupt handler? Or does it only disable that particular interrupt line, which is being served?

Faenza answered 9/7, 2012 at 22:7 Comment(1)
Which CPU? What architecture?Vd
P
5

x86 disables all local interrupts (except NMI of course) before jumping to the interrupt vector. Linux normally masks the specific interrupt and re-enables the rest of the interrupts (which aren't masked), unless a specific flags is passed to the interrupt handler registration.

Note that while this means your interrupt handler will not race with itself on the same CPU, it can and will race with itself running on other CPUs in an SMP / SMT system.

Progesterone answered 11/7, 2012 at 6:46 Comment(3)
Could you please provide the source to the claim "x86 disables all local interrupts .. before jumping to the interrupt vector"? I have in my posession Intel 3-volume architecture documentation, and 8259A documentation, also from Intel. I cannot find anything telling me that interrupts are automatically disabled prior to jumping to interrupt vector, i.e. at the point of entering an ISR (interrupt service routine / interrupt handler procedure)Derian
Not strict HW behavior - the question was asked in the context of the linux kernel. The LAPIC behavior is programmable, but this is how Linux programs it - all interrupts of same priority, so one blocks the other, but Linux in software re-enables interrupts very quickly even before the interrupt handler runs.Progesterone
I subsequently found reference to the "default" x86 HW behavior in question, in "Intel 64 and IA-32 Arch. Software Developer's Manual", p. 6-10 Vol. 1: "If an interrupt or exception handler is called through an interrupt gate, the processor clears the interrupt enable (IF) flag in the EFLAGS register to prevent subsequent interrupts from interfering with the execution of the handler." Thank you for clearing things up w/ regard to Linux.Derian
K
2

Normally (at least in x86), an interrupt disables interrupts.

When an interrupt is received, the hardware does these things:
1. Save all registers in a predetermined place.
2. Set the instruction pointer (AKA program counter) to the interrupt handler's address.
3. Set the register that controls interrupts to a value that disables all (or most) interrupts. This prevents another interrupt from interrupting this one.

An exception is NMI (non maskable interrupt) which can't be disabled.

Kurdish answered 10/7, 2012 at 10:33 Comment(2)
From Linux Kernel Development Interrupt handlers in Linux need not be reentrant. When a given interrupt handler is executing, the corresponding interrupt line is masked out on all processors, preventing another interrupt on the same line from being received. Normally all other interrupts are enabled, so other interrupts are serviced, but the current line is always disabled. Consequently, the same interrupt handler is never invoked concurrently to service a nested interrupt. This greatly simplifies writing your interrupt handler. So, only the current interrupt line is masked.Faenza
@Harman, This means that only the current interrupt line is guaranteed to be masked. I'm pretty sure the actual implementation on x86 is to mask them all.Kurdish
O
1

Yes, that's fine. I'd like to also add what I think might be relevant.

In many real-world drivers/kernel code, "bottom-half" (bh) handlers are used pretty often- tasklets, softirqs. These bh's run in interrupt context and can run in parallel with their top-half (th) handlers on SMP (esp softirq's).

Of course, recently there's a move (mainly code migrated from the PREEMPT_RT project) towards mainline, that essentially gets rid of the 'bh' mechanism- all interrupt handlers will run with all interrupts disabled. Not only that, handlers are (can be) converted to kernel threads- these are the so-called "threaded" interrupt handlers.

As of today, the choice is still left to the developer- you can use the 'traditional' th/bh style or the threaded style.

Ref and Details:

http://lwn.net/Articles/380931/

http://lwn.net/Articles/302043/

Overboard answered 11/7, 2012 at 2:12 Comment(0)
D
0

Quoting Intels own, surprisingly well-written "Intel® 64 and IA-32 Architectures Software Developer’s Manual", Volume 1, pages 6-10:

If an interrupt or exception handler is called through an interrupt gate, the processor clears the interrupt enable (IF) flag in the EFLAGS register to prevent subsequent interrupts from interfering with the execution of the handler. When a handler is called through a trap gate, the state of the IF flag is not changed.

So just to be clear - yes, effectively the CPU "disables" all interrupts before calling the interrupt handler. Properly described, the processor simply triggers a flag which makes it ignore all interrupt requests. Except probably non-maskable interrupts and/or its own software exceptions (please someone correct me on this, not verified).

Derian answered 21/3, 2015 at 14:30 Comment(0)
F
0

We want ISR to be atomic and no one should be able to preempt the ISR.

Therefore, An ISR disables the local interrupts ( i.e. the interrupt on the current processor) and once the ISR calls ret_from_intr() function ( i.e. we have finished the ISR) , interrupts are again enabled on the current processor.

If an interrupt occurs, it will now be served by the other processor ( in SMP system) and ISR related to that interrupt will start running.

In SMP system , We also need to include the proper synchronization mechanism ( spin lock) in an ISR.

Foam answered 22/9, 2015 at 11:50 Comment(1)
Could you please elaborate more your answer adding a little more description about the solution you provide?Pilgarlic

© 2022 - 2024 — McMap. All rights reserved.