Work performed in interrupts includes:. The kernel provides interfaces for:. Because interrupts interrupt other executing code processes, the kernel itself, and even other interrupt handlers , they must execute quickly. Often there is a lot of work to do and to balance the large amount of work with the need for quick execution, the kernel divides the work of processing interrupts into two halves.
The interrupt handler, the top half, was discussed in this chapter. The next chapter looks at the bottom half. Question : What does it mean? Question : Why is it dangerous? Search this site. Embedded questions. Chapter Introduction to the Linux Kernel.
Getting Started with the Kernel. Process Management. System Calls. Kernel Data Structures. Interrupts and Interrupt Handlers. Bottom Halves and Deferring Work.
Memory Management. Contents 1 Interrupts 1. Introduction to the Linux Kernel Chapter Getting Started with the Kernel Chapter Process Management Chapter System Calls Chapter Kernel Data Structures Chapter Interrupts and Interrupt Handlers Chapter Bottom Halves and Deferring Work Chapter Memory Management Chapter Interrupts and Interrupt Handlers Contents 1 Interrupts 1.
Interrupts Interrupts enable hardware to signal to the processor. For example, as you type, the keyboard controller the hardware device that manages the keyboard issues an electrical signal to the processor to alert the operating system to newly available key presses. These electrical signals are interrupts. The processor receives the interrupt and signals the operating system to enable the operating system to respond to the new data. Hardware devices generate interrupts asynchronously with respect to the processor clock.
Consequently, the kernel can be interrupted at any time to process interrupts. An interrupt is produced by electronic signals from hardware devices and directed into input pins on an interrupt controller a simple chip that multiplexes multiple interrupt lines into a single line to the processor : Upon receiving an interrupt, the interrupt controller sends a signal to the processor.
The processor detects this signal and interrupts its current execution to handle the interrupt. The processor can then notify the operating system that an interrupt has occurred, and the operating system can handle the interrupt appropriately.
Some interrupts are dynamically assigned, such as interrupts associated with devices on the PCI bus. Other non-PC architectures have similar dynamic assignments for interrupt values. The kernel knows that a specific interrupt is associated with a specific device. The hardware then issues interrupts to get the kernel's attention. Simple definitions of the two: Interrupts : asynchronous interrupts generated by hardware.
Exceptions : synchronous interrupts generated by the processor. Interrupt Handlers An interrupt handler or interrupt service routine ISR is the function that the kernel runs in response to a specific interrupt: Each device that generates interrupts has an associated interrupt handler.
The interrupt handler for a device is part of the device's driver the kernel code that manages the device. It is important that To the hardware: the operating system services the interrupt without delay. To the rest of the system: the interrupt handler executes in as short a period as possible.
Top Halves Versus Bottom Halves These two goals of an interrupt handler conflict with one another: Execute quickly Perform a large amount of work Because of these competing goals, the processing of interrupts is split into two parts, or halves : Top half. The interrupt handler is the top half. The top half is run immediately upon receipt of the interrupt and performs only the work that is time-critical, such as acknowledging receipt of the interrupt or resetting the hardware.
Bottom half. Work that can be performed later is deferred until the bottom half. The bottom half runs in the future, at a more convenient time, with all interrupts enabled. For example using the network card: When network cards receive packets from the network, the network cards immediately issue an interrupt.
This optimizes network throughput and latency and avoids timeouts. CPUs rely on the data contained in a couple registers to correctly handle interrupts.
One register holds a pointer to the process control block of the current running process. This register is set each time a process is loaded into memory. The other register holds a pointer to a table containing pointers to the instructions in the OS kernel for interrupt handlers and system calls. The value in this register and contents of the table are set when the operating system is initialized at boot time. The CPU uses a table and the interrupt vector to find OS the code to execute in response to interrupts.
A software interrupt is shown here. As the computer runs, processing switches between user processes and the operating system as hardware and software interrupts are received. Computer Architecture. Parts of an Operating System.
The job of the interrupt handler is to service the device and stop the device from interrupting. When the interrupt handler returns, the CPU resumes the work it was doing before the interrupt occurred. Both methods commonly supply a bus-interrupt priority level.
Vectored devices also supply an interrupt vector. Polled devices do not supply interrupt vectors. To stay current with changing bus technologies, the Solaris OS has been enhanced to accommodate both newer types of interrupts and more traditional interrupts that have been in use for many years.
Specifically, the operating system now recognizes three types of interrupts:. Legacy interrupts — Legacy or fixed interrupts refer to interrupts that use older bus technologies. Newer bus technologies such as PCI Express maintain software compatibility by emulating legacy interrupts through in-band mechanisms.
These emulated interrupts are treated as legacy interrupts by the host OS. Message-signaled interrupts — Instead of using pins, message-signaled interrupts MSI are in-band messages and can target addresses in the host bridge.
MSIs can send data along with the interrupt message. MSI-X interrupts have the following added advantages:. Enable more flexibility when software allocates fewer vectors than hardware requests. INTx emulation is used for compatibility purposes, but is not considered to be good practice.
A bus prioritizes a device interrupt at a bus-interrupt level. The bus interrupt level is then mapped to a processor-interrupt level.
A bus interrupt level that maps to a CPU interrupt priority above the scheduler priority level is called a high-level interrupt. High-level interrupt handlers are restricted to calling the following DDI interfaces:. A bus-interrupt level by itself does not determine whether a device interrupts at a high level.
A particular bus-interrupt level can map to a high-level interrupt on one platform, but map to an ordinary interrupt on another platform. A driver is not required to support devices that have high-level interrupts.
However, the driver is required to check the interrupt level. If the interrupt priority is greater than or equal to the highest system priority, the interrupt handler runs in high-level interrupt context.
In this case, the driver can fail to attach, or the driver can use a two-level scheme to handle interrupts. For more information, see Handling High-Level Interrupts. The only information that the system has about a device interrupt is the priority level of the bus interrupt and the interrupt request number. When an interrupt handler is registered, the system adds the handler to a list of potential interrupt handlers for each IPL or IRQ.
When the interrupt occurs, the system must determine which device actually caused the interrupt, among all devices that are associated with a given IPL or IRQ. A message-signaled interrupt is posted as a write with an address and value that are specified by the software. An MSI is an in-band message that is implemented as a posted write. The address and the data for the MSI are specified by software and are specific to the host bridge. By definition, MSI interrupts are unshared.
Each MSI message that is assigned to a device is guaranteed to be a unique message in the system. Note that the system software can allocate fewer MSI messages to a function than the function requested. The host bridge can be limited in the number of unique MSI messages that are allocated for devices. With MSI-X interrupts, an unallocated interrupt vector of a device can use a previously added or initialized MSI-X interrupt vector to share the same vector address, vector data, interrupt handler, and handler arguments.
A duplicated interrupt is disabled initially. You cannot remove the original MSI-X interrupt handler until all duplicated interrupt handlers that are associated with this original interrupt handler are removed. Soft interrupts are initiated by software rather than by a hardware device.
Handlers for these interrupts must also be added to and removed from the system. Soft interrupt handlers run in interrupt context and therefore can be used to do many of the tasks that belong to an interrupt handler. Hardware interrupt handlers must perform their tasks quickly, because the handlers might have to suspend other system activity while doing these tasks. This requirement is particularly true for high-level interrupt handlers, which operate at priority levels greater than the priority level of the system scheduler.
High-level interrupt handlers mask the operations of all lower-priority interrupts, including the interrupt operations of the system clock. Consequently, the interrupt handler must avoid involvement in activities that might cause it to sleep, such as acquiring a mutex. If the handler sleeps, then the system might hang because the clock is masked and incapable of scheduling the sleeping thread.
For this reason, high-level interrupt handlers normally perform a minimum amount of work at high-priority levels and delegate other tasks to software interrupts, which run below the priority level of the high-level interrupt handler.
Because software interrupt handlers run below the priority level of the system scheduler, software interrupt handlers can do the work that the high-level interrupt handler was incapable of doing. Interrupt management interfaces enable you to manipulate priorities, capabilities, and interrupt masking, and to obtain pending information. Use the following functions to obtain interrupt information:. Use the following functions to create and remove interrupts:.
Use with MSI-X only. Copies an address and data pair for an allocated interrupt vector to an unused interrupt vector on the same device. Reads the interrupt pending bit if such a bit is supported by either the host bridge or the device. Use the following functions to obtain and set priority information:. Use the following functions to manipulate soft interrupts and soft interrupt handlers:. This section provides examples for performing the following tasks:.
If you're working with interrupts, you might see an Out of Interrupt Events error. This happens when the system is no longer able to run user code and is stuck in the kernel, most frequently because:. If you call InterruptAttach in your code, look at the handler code first and make sure you're properly clearing the interrupt condition from the device before returning to the OS. If you encounter this problem, and you're sure all your interrupt handlers are fine, it could be caused by broken interrupt callouts in the BSP.
It's possible for different devices to share an interrupt for example if you've run out of hardware interrupt lines , but we don't recommend you do this with hardware that will be generating a lot of interrupts. We also recommend you not share interrupts with drivers that you don't have complete source control over, because you need to be sure that the drivers process interrupts properly. Sharing interrupts can decrease your performance, because when the interrupt fires, all of the devices sharing the interrupt need to run and check to see if it's for them.
Many drivers read the registers in their interrupt handlers to see if the interrupt is really for them, and then ignore it if it isn't. But some drivers don't; they schedule their thread-level event handlers to check their hardware, which is inefficient and reduces performance.
Sharing interrupts can increase interrupt latency, depending upon exactly what each of the drivers does. After an interrupt fires, the kernel doesn't reenable it until all driver handlers tell the kernel that they've finished handling it. If one driver takes a long time servicing a shared interrupt that's masked, and another device on the same interrupt causes an interrupt during that time period, the processing of that interrupt can be delayed for an unknown length of time.
Now that we've seen the basics of handling interrupts, let's take a look at some more details and some advanced topics. When your ISR is running, it runs in the context of the process that attached it, except with a different stack. Since the kernel uses an internal interrupt-handling stack for hardware interrupts, your ISR is impacted in that the internal stack is small.
Generally, you can assume that you have about bytes available. Another factor of concern for realtime systems is the amount of time taken between the generation of the hardware interrupt and the first line of code executed by the ISR. There are two factors to consider here:.
Using these functions alleviates the need to disable and enable interrupts around certain small, well-defined operations with variables, such as:.
The startup code is responsible for making sure that all interrupt sources are masked during system initialization. When the first call to InterruptAttach or InterruptAttachEvent is done for an interrupt vector, the kernel unmasks it.
Similarly, when the last InterruptDetach is done for an interrupt vector, the kernel remasks the level. It isn't safe to use floating-point operations in Interrupt Service Routines.
Since the range of hardware attached to an interrupt source can be very diverse, the specific how-to's of servicing the interrupt are beyond the scope of this document — this really depends on what your hardware requires you to do.
We recommend that you always use the SMP versions of these functions — this makes your code portable to SMP systems, with a negligible amount of overhead. If you have a frequent interrupt source sharing an interrupt with a driver that schedules a thread to check the hardware, the overhead of scheduling the thread becomes noticeable.
0コメント