Here's a high-level view of the low-level processing. I'm describing a simple typical architecture, real architectures can be more complex or differ in ways that don't matter at this level of detail.

When an interrupt occurs, the processor looks if interrupts are masked. If they are, nothing happens until they are unmasked. When interrupts become unmasked, if there are any pending interrupts, the processor picks one.

Then the processor executes the interrupt by branching to a particular address in memory. The code at that address is called the interrupt handler. When the processor branches there, it masks interrupts (so the interrupt handler has exclusive control) and saves the contents of some registers in some place (typically other registers).

The interrupt handler does what it must do, typically by communicating with the peripheral that triggered the interrupt to send or receive data. If the interrupt was raised by the timer, the handler might trigger the OS scheduler, to switch to a different thread. When the handler finishes executing, it executes a special return-from-interrupt instruction that restores the saved registers and unmasks interrupts.

The interrupt handler must run quickly, because it's preventing any other interrupt from running. In the Linux kernel, interrupt processing is divided in two parts:

  • The “top half” is the interrupt handler. It does the minimum necessary, typically communicate with the hardware and set a flag somewhere in kernel memory.
  • The “bottom half” does any other necessary processing, for example copying data into process memory, updating kernel data structures, etc. It can take its time and even block waiting for some other part of the system since it runs with interrupts enabled.

As usual on this topic, for more information, read Linux Device Drivers; chapter 10 is about interrupts.

Answer from Gilles 'SO- stop being evil' on Stack Exchange
🌐
Linux Kernel Labs
linux-kernel-labs.github.io › refs › heads › master › lectures › interrupts.html
Interrupts — The Linux Kernel documentation
(void *) 0xc15de780 <entry_SYSENTER_32> ... + 8 * 128) monitor info registers · In Linux the interrupt handling is done in three phases: critical, immediate and deferred....
🌐
O'Reilly
oreilly.com › library › view › linux-device-drivers › 0596005903 › ch10.html
10. Interrupt Handling - Linux Device Drivers, 3rd Edition [Book]
February 7, 2005 - An interrupt is simply a signal that the hardware can send when it wants the processor’s attention. Linux handles interrupts in much the same way that it handles signals in user space.
Authors   Jonathan CorbetAlessandro Rubini
Published   2005
Pages   636
Discussions

Linux - Interrupt Handling: Overview (Part 1)
Thanks for all the articles you wrote. Very interesting! More on reddit.com
🌐 r/linux
15
284
December 18, 2022
Interrupts and Interrupt Handling in Arch Linux
interrupts are handled by the kernel. You can also install irqbalance to make it handle interrupts More on reddit.com
🌐 r/linuxquestions
3
0
November 9, 2022
Do interrupts actual interrupt or do they wait for a 'natural' context switch and jump the queue?
The short answer is that when an interrupt happens, the interrupt handler runs. A well-behaved interrupt handler saves CPU state, runs quickly without blocking, and then restores CPU state. This context switch happens whether or not the current thread is ultimately preempted. In modern OSes, the handler is divided into two parts : the part that quickly handles the actual interrupt, and the part that does the bulk of the work later. More on reddit.com
🌐 r/C_Programming
36
51
February 8, 2025
Is it possible to implement try/catch exception handling in a programming language that transpiles to C?
Yes, because Turing completeness. Yes, just use longjmp. That's the way it was done historically. Yes, check out the wild shenanigans that Chicken Scheme manages to compile down into C! Yes: The C++ community is currently having a discussion about alternatives to exceptions that come with less runtime overhead. See: Zero-overhead deterministic exceptions: Throwing values status_code and standard error object for Zero-overhead deterministic exceptions C++ exceptions and alternatives P0323R10: std::expected More on reddit.com
🌐 r/cprogramming
18
5
November 29, 2023
Top answer
1 of 3
45

Here's a high-level view of the low-level processing. I'm describing a simple typical architecture, real architectures can be more complex or differ in ways that don't matter at this level of detail.

When an interrupt occurs, the processor looks if interrupts are masked. If they are, nothing happens until they are unmasked. When interrupts become unmasked, if there are any pending interrupts, the processor picks one.

Then the processor executes the interrupt by branching to a particular address in memory. The code at that address is called the interrupt handler. When the processor branches there, it masks interrupts (so the interrupt handler has exclusive control) and saves the contents of some registers in some place (typically other registers).

The interrupt handler does what it must do, typically by communicating with the peripheral that triggered the interrupt to send or receive data. If the interrupt was raised by the timer, the handler might trigger the OS scheduler, to switch to a different thread. When the handler finishes executing, it executes a special return-from-interrupt instruction that restores the saved registers and unmasks interrupts.

The interrupt handler must run quickly, because it's preventing any other interrupt from running. In the Linux kernel, interrupt processing is divided in two parts:

  • The “top half” is the interrupt handler. It does the minimum necessary, typically communicate with the hardware and set a flag somewhere in kernel memory.
  • The “bottom half” does any other necessary processing, for example copying data into process memory, updating kernel data structures, etc. It can take its time and even block waiting for some other part of the system since it runs with interrupts enabled.

As usual on this topic, for more information, read Linux Device Drivers; chapter 10 is about interrupts.

2 of 3
26

Gilles already described the general case of an interrupt, the following applies specifically to Linux 2.6 on an Intel architecture (part of this is also based on Intel's specifications).

An interrupt is an event that changes the sequence of instructions executed by the processor.
There are two different kinds of interrupts:

  • Synchronous interrupt (Exception) produced by the CPU while processing instructions
  • Asynchronous interrupt (Interrupt) issued by other hardware devices

Exceptions are caused by programming errors (f.e. Divide error, Page Fault, Overflow) that must be handled by the kernel. He sends a signal to the program and tries to recover from the error.

The following two exceptions are classified:

  • Processor-detected exception generated by the CPU while detecting a anomalous condition; divided into three groups: Faults can generally be corrected, Traps report an execution, Aborts are serious errors.
  • Programmed exception requested by the programmer, handled like a trap.

Interrupts can be issued by I/O devices (keyboard, network adapter, ..), interval timers and (on multiprocessor systems) other CPUs. When an interrupt occures, the CPU must stop his current instruction and execute the newly arrived interrupt. He needs to save the old interrupted process state to (probably) resume it after the interrupt is handled.

Handling interrupts is a sensitive task:

  • Interrupts can occur at any time, the kernel tries to get it out of the way as soon as possible
  • An interrupt can be interrupted by another interrupt
  • There are regions in the kernel which must not be interrupted at all

Two different interrupt levels are defined:

  • Maskable interrupts issued by I/O devices; can be in two states, masked or unmasked. Only unmasked interrupts are getting processed.
  • Nonmaskable interrupts; critical malfunctions (f.e. hardware failure); always processed by the CPU.

Every hardware device has it's own Interrupt Request (IRQ) line. The IRQs are numbered starting from 0. All IRQ lines are connected to a Programmable Interrupt Controller (PIC). The PIC listens on IRQs and assigns them to the CPU. It is also possible to disable a specific IRQ line.
Modern multiprocessing Linux systems generally include the newer Advanced PIC (APIC), which distributes IRQ requests equally between the CPUs.

The mid-step between an interrupt or exception and the handling of it is the Interrupt Descriptor Table (IDT). This table associates each interrupt or exception vector (a number) with a specified handler (f.e. Divide error gets handled by the function divide_error()).

Through the IDT, the kernel knows exactly how to handle the occurred interrupt or exception.


So, what does the kernel when an interrupt occurres?

  • The CPU checks after each instruction if there's a IRQ from the (A)PIC
  • If so, consults the IDT to map the received vector to a function
  • Checks if the interrupt was issued by a authorized source
  • Saves the registers of the interrupted process
  • Call the according function to handle the interrupt
  • Load the recently saved registers of the interrupted process and try to resume it
🌐
Embien
embien.com › blog › advanced-interrupt-handling-in-Linux
Advanced Interrupt Handling Techniques in Linux
July 28, 2024 - Advanced interrupt handling in Linux: interrupt contexts, deferred interrupt handling with softirqs and tasklets, interrupt flags in Linux, and efficient ISR techniques.
🌐
Baeldung
baeldung.com › home › processes › interrupt handling in linux
Interrupt Handling in Linux | Baeldung on Linux
March 19, 2025 - Recent Linux systems distribute the IRQ among the cores with the Advanced PIC (APIC). We need to tweak the IRQ if we want to mask some interrupts. In the following figure, we can see how the architecture is between these components: We can see in the previous image that there is yet another step between a device invoking an interrupt and its handling: the Interrupt Descriptor Table (IDT).
🌐
Opensource.com
opensource.com › article › 20 › 10 › linux-kernel-interrupts
How the Linux kernel handles interrupts | Opensource.com
October 5, 2020 - An abort invokes the system's abort exception handler, which terminates the process that caused it. IRQs are ordered by priority in a vector on the APIC (0=highest priority). The first 32 interrupts (0–31) have a fixed sequence that is specified by the CPU. You can find an overview of them on OsDev's Exceptions page. Subsequent IRQs can be assigned differently. The interrupt descriptor table (IDT) contains the assignment between IRQ and ISR. Linux defines an IRQ vector from 0 to 256 for the assignment.
🌐
O'Reilly
oreilly.com › library › view › understanding-the-linux › 0596005652 › ch04s06.html
4.6. Interrupt Handling - Understanding the Linux Kernel, 3rd Edition [Book]
November 17, 2005 - As we explained earlier, most exceptions are handled simply by sending a Unix signal to the process that caused the exception. The action to be taken is thus deferred until the process receives the signal; as a result, the kernel is able to process the exception quickly. This approach does not hold for interrupts, because they frequently arrive long after the process to which they are related (for instance, a process that requested a data transfer) has been suspended and a completely unrelated process is running.
Authors   Daniel P. BovetMarco Cesati
Published   2005
Pages   942
Find elsewhere
🌐
Linux Kernel
kernel.org › doc › html › v4.12 › core-api › genericirq.html
Linux generic IRQ handling — The Linux Kernel documentation
The original implementation of interrupt handling in Linux uses the __do_IRQ() super-handler, which is able to deal with every type of interrupt logic.
🌐
Reddit
reddit.com › r/linux › linux - interrupt handling: overview (part 1)
r/linux on Reddit: Linux - Interrupt Handling: Overview (Part 1)
December 18, 2022 -

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
🌐
The Linux Documentation Project
tldp.org › LDP › lkmpg › 2.6 › html › x1256.html
12.1. Interrupt Handlers
Under Linux, hardware interrupts are called IRQ's (InterruptRe quests)[1]. There are two types of IRQ's, short and long. A short IRQ is one which is expected to take a very short period of time, during which the rest of the machine will be blocked and no other interrupts will be handled...
🌐
EmbeTronicX
embetronicx.com › tutorials › linux › device-drivers › linux-device-driver-tutorial-part-13-interrupt-example-program-in-linux-kernel
Interrupt Example Program in Linux Kernel | Interrupt Handling
September 24, 2023 - static irqreturn_t irq_handler(int irq,void *dev_id) { printk(KERN_INFO "Shared IRQ: Interrupt Occurred"); return IRQ_HANDLED; } The interrupt can be coming from anywhere (any hardware) and anytime. In our tutorial, we are not going to use any hardware. Here, instead of using hardware, we are going to trigger interrupt by simulating. If you have only a PC (without hardware), but you want to play around with Interrupts in Linux, you can follow our method.
🌐
XML.com
xml.com › ldd › chapter › book › ch09.html
Linux Device Drivers, 2nd Edition: Chapter 9: Interrupt Handling
In many situations, modules are also expected to be able to share interrupt lines with other drivers, as we will see. The following functions, declared in <linux/sched.h>, implement the interface: int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id); void free_irq(unsigned int irq, void *dev_id);
🌐
The Linux Documentation Project
tldp.org › LDP › tlk › dd › interrupts.html
Chapter 7 Interrupts and Interrupt Handling
The kernel's interrupt handling data structures are set up by the device drivers as they request control of the system's interrupts. To do this the device driver uses a set of Linux kernel services that are used to request an interrupt, enable it and to disable it.
🌐
EmbeTronicX
embetronicx.com › tutorials › linux › device-drivers › interrupts-in-linux-kernel
Interrupts in Linux Kernel - Linux Device Driver Tutorial Part 12
May 19, 2023 - The interrupt handler for a device ... interrupt handlers are normal C functions, which match a specific prototype and thus enable the kernel to pass the handler information in a standard way....
🌐
Linux Foundation
training.linuxfoundation.org › home › webinars › interrupt handling in linux device drivers
Interrupt Handling in Linux Device Drivers - Linux Foundation - Education
April 12, 2019 - This 20-minute clip provides useful information on “Interrupt Handling: Deferrable Functions and User Drivers.” The course covers top halves and bottom halves, methods for implementing bottom halves, how to create your own kernel threads, the most recent API for threaded interrupt handlers and how to do interrupt handling from inside user space instead of the kernel module. ... Jerry Cooperstein has been working with Linux since 1994, developing and delivering training in both the kernel and user space.
🌐
Linux Kernel Labs
linux-kernel-labs.github.io › refs › heads › master › labs › interrupts.html
I/O access and Interrupts — The Linux Kernel documentation
Because such a situation is relatively common, the kernel provides the request_threaded_irq() function to write interrupt handling routines running in two phases: a process-phase and an interrupt context phase: #include <linux/interrupt.h> int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags, const char *name, void *dev);
🌐
GitHub
github.com › ANSANJAY › InterruptHandlinginKernel
GitHub - ANSANJAY/InterruptHandlinginKernel: A deep dive into the interrupt handling mechanisms within the Linux kernel. Explore how different devices, from keyboards to Ethernet ports, trigger and process interrupts. Complete with hands-on examples and real-world use cases. · GitHub
A deep dive into the interrupt handling mechanisms within the Linux kernel. Explore how different devices, from keyboards to Ethernet ports, trigger and process interrupts. Complete with hands-on examples and real-world use cases. - ANSANJAY/InterruptHandlinginKernel
Starred by 10 users
Forked by 2 users
Languages   C 91.5% | Makefile 8.5%
🌐
Medium
medium.com › @m_tran80 › interrupt-handling-in-the-linux-kernel-a-deep-dive-into-system-level-event-management-fb9250618921
Interrupt Handling in the Linux Kernel: A Deep Dive into System-Level Event Management | by Minh Huy Tran | Medium
February 11, 2025 - Prioritizes critical interrupts, reducing context switch overhead and ensuring timely execution of high-priority tasks. Interrupt handling is the backbone of responsive and efficient operating systems like Linux.
🌐
Embien
embien.com › blog › writing-interrupt-service-routines-for-linux
Writing Interrupt Service Routines for Linux
July 21, 2024 - By implementing well-designed interrupt service routines for Linux, one can efficiently manage these interrupts and ensure that your system remains responsive and reliable. Before we dive into the process of writing ISRs, let's first explore some of the key concepts related to interrupt handling in Linux: Interrupt Vectors:
🌐
Site24x7
site24x7.com › learn › linux › kernel-hardware-interrupts.html
What are hardware interrupts, and how do Linux kernels handle them: Site24x7
The ISR handles the request event ... complete, the CPU will resume the process. Interrupt handling is the most complicated task controlled by the Linux kernel....