Videos
After talking in general about the concept of interrupts (https://medium.com/@boutnaru/computer-architecture-interrupts-9d0dc849c1e5) now we are going to deep dive into how they are handled under Linux.
In order to handle an interrupt we first need to register it using a call to “request_irq” which adds the handler (https://elixir.bootlin.com/linux/v6.1/source/include/linux/interrupt.h#L165). In order to remove a handler we call “free_irq”. Fun fact, “request_irq” is referenced in 1280 files in the source code of the Linux kernel (version 6.1).
Overall, we can think about two major use cases when we are handling interrupts. First, interrupts that are designed to execute quickly. Second, interrupts which have to do several operations to complete (meaning they won’t execute quickly).
Due to that, interrupt handling has two phases (by the way it is true not only for Linux). We have “Top Half” and “Bottom Half”. The main reason for the split is the fact that we can’t perform large operations in interrupt-context (when interrupts are disable). So, what “Bottom Half” allows us is to defer work for later. For more information I suggest reading https://0xax.gitbooks.io/linux-insides/content/Interrupts/linux-interrupts-9.html.
We can sum up the phases of a “Top Half” as follows: ensure that the interrupt was triggered by the correct hardware (in case of line sharing), clearing interrupt pending bit on the hardware (if needed), does everything that needs to be immediate (like reading/writing to/from the device) and schedule the “Bottom Half” (if needed). As an example we can see the interrupt handler for a floppy (https://elixir.bootlin.com/linux/v6.1/source/drivers/block/floppy.c#L1712) that calls the deferred work in the following line https://elixir.bootlin.com/linux/v6.1/source/drivers/block/floppy.c#L1765.
Thus, “Top Half” runs in an interrupt context, which is used for quick responses to external events and it is responsible for creating the deferred work for later (the “Bottom Half”) - as we can see in the timeline diagram shown below.
Lastly, We have three types for the category of “Bottom Half”: workques, tasklets and softirq (https://www.oreilly.com/library/view/understanding-the-linux/0596002130/ch04s07.html). We will dive into each one of them in future writeups. By the way, there are also timers and normal regular kernel threads that can be used for deferred work but they are less natural for interrupt handling so I won’t go over them in this series.
Next we are going to start diving into workques, tasklets and softirq. See you in the next writeup :-).
https://hugh712.gitbooks.io/embeddedsystem/content/Images/RealTime/RT006.png