Why are interrupts disabled when the kernel is currently handling an interrupt ?
What if an interrupt carrying an important message is missed ?
Why are interrupts disabled when the kernel is currently handling an interrupt ?
What if an interrupt carrying an important message is missed ?
This prevents "stacked interrupts" that can overflow the kernel stack. It also can also prevent deadlocks and/or "pinning".
Most hardware doesn't "lose" an interrupt. During an interrupt, the CPU's "interrupt flag" is cleared, but the interrupt controller [a separate beast] is still available/enabled to note new interrupts. If the CPU is processing an interrupt for hardware_A (in "interrupt service routine" ISR_A), the interrupt for hardware_B can still be asserted. It will be remembered [by the interrupt controller], it just won't interrupt the CPU at that time. When ISR_A returns, the interrupt flag is reenableed on exit, and now, immediately, ISR_B will be entered (and its call stack frame will start at the same exact memory location as for ISR_A).
While interrupts won't be missed/dropped, ISRs should be short [execute quickly] to minimize latency. In other words, ISR_A should not take so long that hardware_B will overflow some internal state/buffer [as it continues to accumulate data while waiting for ISR service].
Minimizing latency is a part of careful kernel design and ISR design. In Linux, ISRs can be broken down into the ISR part and a "bottom half" or "tasklet" part. The ISR [with interrupts disabled] does the minimum needed to service/quiesce the device (e.g. clear a bit in the device to prevent it from reasserting the interrupt immediately).
It then enables its corresponding tasklet [which runs with interrupts enabled] to do the more laborous operations that may take longer. Tasklets, despite the name, aren't like full blown tasks/processes that show up in "ps". They're a [very] lightweight/efficient way of splitting up the work the ISR must do, to minimize latency.
Let's take each question.
Why are interrupts disabled when the kernel is currently handling an interrupt ?
Though there are many types of interrupts, such as I/Os, timers, watchdogs, serial ports,peripherals and DMA, let's take example of I/Os. We'll talk a raw case and extend it into kernel.
Imagine a fire-alarm/sensor bit 0/1 connected to your CPU's particular interrupt pin. 0 is normal state and 1 is fire! Then one would configure that input's interrupt as "level triggered". The moment the sensor fires 1, the ISR has to execute a relevant code to siren or automatically dial fire department. An interrupt should be generally cleared the moment you enter ISR. If it's not cleared, the hardware keeps interrupting the CPU and the safety code inside ISR will never execute.
Also the CPU needs to maintain a stack of its current execution state. A recurring interrupt makes it a complex situation.
Second example with a "edge triggered" or "transition triggered" Imagine a series of bits are coming on an input line/pin (NRZ coded). If the ISR's job is assembling those bits into words (8,16,32 whatever length), we need to clear the interrupt, assemble the bit into buffer, and enable the interrupt again, in cycles. Not clearing the interrupt would cause a glitch-y transition to mistake just 1 bit as 2 bits.
So the practice is setup and enable the interrupts, if interrupted, clear it, execute the ISR code and enable the interrupts back wherever relevant.
Kernel
Kernel itself is a critical piece of code and scheduler (also OS timer, OS Clock) depend on a hardware timers interrupt. The hardware part of the CPU that contains interrupt logic maintains state-transition. It also has hardwired logic for enabling, disabling, masking and setting interrupt priorities.
If a kernel module or diver module should execute code safely, a deterministic behavior can only be obtained by disabling the interrupt before executing the handler.
What if an interrupt carrying an important message is missed ?
The interrupt handling shouldn't be too long (before enabling back the interrupts). One should design code properly depending on the frequency of interrupts and complexity of handler.
If any interrupt is asserted to controller, it can't be delivered to CPU as INTR line is busy in handling the first interrupt.
But more importantly interrupts can be delivered to other CPU, now a days multi CPU systems are quite common.
And as first reply - always keep the interrupt handler small and lightweight. Can have any bottom half approach like tasklet, workqueue, threaded IRQ, can create kernel threads. You can get multiple SOFT IRQ options.
© 2022 - 2024 — McMap. All rights reserved.