Presentation on theme: "Tutorial 3 - Linux Interrupt Handling -"— Presentation transcript:
1Tutorial 3 - Linux Interrupt Handling - Bogdan Simion
2Today’s tutorial Getting started with Linux programming Interrupt need and interrupt typesHardware support for interruptsInterrupt handling processUpper and bottom halvesConcurrency considerationsImplementing an interrupt handler
3Getting started Linux Kernel Development, by Robert Love High-level, good starting pointUnderstanding the Linux Kernel, by D.Bovet and M.CesatiMore advanced, lots of detailsLinux Device Drivers, A.Rubini and J.CorbetCross-reference Linux sources – with hyperlinks!Really useful to understand code and data structures
4InterruptsAn event external to the currently executing process that causes a change in the normal flow of instruction execution; usually generated by hardware devices external to the CPUAsynchronous w.r.t current processExternal & internal devices need CPU serviceCPU must detect devices that require attention!
5Alternatives Polling: CPU checks each device periodically Too much overhead - CPU time wasted pollingEfficient if events arrive fast, or if not urgent (slow polling at large intervals)Interrupts: Each device gets an “interrupt line”Device signals CPU when it needs attention, CPU handles request when it comes inNo overhead / wasted cyclesGood for events that are urgent, and/or infrequent
6Interrupt typesHardware: An event/electronic signal from external device that needs CPU attentionMouse moved, keyboard pressedPrinter ready, modem, etcSoftware:exceptions (traps) in the processor: divide by zero exception, page faults, etc.special software interrupt instructions (e.g., request disk reads/writes to disk controller)
7Hardware support for interrupts Devices are connected to a shared message bus to the APICLimited number of IRQ linesAfter every instruction (user-mode), CPU checks for hardware interrupt signals and, if present, calls an interrupt handler (kernel routine)Advanced Programmable Interrupt Controller
8Load Interrupt Handler Interrupt handlingProgram instructionInterrupt pendingYESSwitch to kernel modeNOSave current PCInterrupt detected => Switch to kernel mode => Push PC onto stack=> Load PC of interrupt handler from IVT (Interrupt Vector Table)The IVT is the list of handler addresses, and it’s mapped into kernel memory space so we can retrieve the interrupt handler fast.Load Interrupt HandlerExecute IHRestore PCProgram instruction
9Interrupt Descriptor Table x86 implementation of IVT for fast interrupt handlingReserved chunk of RAM, used by the CPU to quickly branch to a specific interrupt handlerMapped to kernel space at 0x0000-0x03ff (256 4-byte pointers) on 8086Later CPUs: flexible locations and different sizeFirst 32 entries (0x00-0x1F) - reserved for mapping handlers for CPU-specific exceptions (faults)Next entries – interrupt routines (e.g., keyboard)An Interrupt Vector Table (IVT) is a list of handler addresses that the CPU has to determine which interrupt handler to dispatch for each interrupt code.On x86 architectures, we have something called the IDT – provides special instr and data structures managed by the CPU itself so the interrupt handling can be as fast as possible.32 and up -> Keyboard, video, IDE, etc
10Interrupt handlers Fast/Hard/First-Level Interrupt Handler (FLIH) Quickly service an interrupt, minimal exec timeSchedule SLIHs if neededSlow/Soft/Second-Level Interrupt Handler (SLIH)Long-lived interrupt processing tasksLower priority - sit in a task runqueueExecuted by a pool of kernel threads, when no FLIHsLinux:FLIHs = upper halves (UH)SLIHs = bottom halves (BH)WindowsDeferred Procedure Calls (DPCs)FLIHs implement a minimum platform-specific interrupt handling – goal is to quickly service the interrupt, and schedule the execution of a SLI for further long-lived interrupt handling.SLIHs – take longer to execute, lower priority, executed whenever CPU is not executing a fast interrupt handlerFor instance, when a network interface reports the arrival of a new packet, the handler just retrieves the data and pushes it up to the protocol layer; actual processing of the packet is performed in a bottom half.
11Bottom halves (BH) SoftIRQs and Tasklets Workqueues Deferred work runs in interrupt contextDon’t run in process contextCan’t sleepTasklets somewhat easier to useWorkqueuesRun in kernel threadsSchedulableCan sleepAlso can’t block on a mutex.
12ConcurrencyHardware interrupts (IRQs) can arrive while a specific interrupt handler is in executionFast interrupts must run atomically => Disable all interrupts and restore them when doneAs a result, fast interrupts must run fast, and defer long-lived work to bottom halves.Otherwise => interrupt storm => livelocksIf FLIHs take too long, then other devices that require attention are waiting. Worse, same device might have more data to deliver to the OS before previous data is completely received. This can cause h/w failures, buffer overflows, dropped data, messages, etc.Inside the OS, this can lead to an interrupt storm: whenever there’s always an interrupt waiting whenever a fast int handler finishes its execution. This could occur either because the FLIH takes too long, or H/W has bugs. If the OS is continuously handling interrupts, it never runs any application code (livelock). So it never appears to respond to user inputs, the user sees the system as being frozen even though it’s running.
13Interrupt enablingIE (Interrupt Enable) bit in the status register can be set or reset by the processorcli = clear interruptssti = set interruptsMust be careful with semantics if using these directlycli disables interrupts on ALL processorsIf you are already handling an IRQ, cli only disables them on current CPUBasically CPU can decide to ignore the PIC’s requests and continue running, if IF (interrupt flag) is disabled in the status registerGenerally discouraged to use cli/sti directly.
14MultiprocessorsLinux kernel tries to divide interrupts evenly across processors to some extentFast interrupts (SA_INTERRUPT) execute with all other interrupts disabled on the current processorOther processors can still handle interrupts, though not the same IRQ at the same time
15Interrupt handling internals (x86) Each interrupt goes through do_IRQA do_IRQ acquires spinlock on the irq#, preventing other CPUs from handling this IRQLooks up handlerIf no handler, schedule bottom halves (if any) and returnIf handler, run handle_IRQ_event to invoke the handlers
16Implementing an interrupt handler Use request_irq()to get interrupt handlerirq (IRQ number)handler (func. pointer - interrupt handler)flags (SA_INTERRUPT, SA_SHIRQ, etc)dev_name (string used in /proc/interrupts)dev_id (used for shared interrupt lines)Fast handler - always with SA_INTERRUPTFrom within interrupt handler, schedule BH to run (tasklet_schedule, queue_work, etc.)Dev_name: – name of the device that registered this handler for the current interrupt “irq” (1st param)
17Implementing an interrupt handler(2) A driver might need to disable/enable interrupt reporting for its own IRQ line onlyKernel functions:disable_irq (int irq)disable_irq_nosync (int irq)enable_irq (int irq)Enable/disable IRQ - across ALL processorsNosync – doesn’t wait for currently executing IH’s to complete => faster, but leaves driver open to race conditionsDisable_irq will not only disable that IRQ but will also wait for a currently executing interrupt handler, if any, to complete.Disable_irq will return immediately -> faster, but leaves your driver open to race conditions.Enable/disable this IRQ across all processors.IRQ lines are H/W lines on which devices can send interrupt signals to the processor (the APIC actually). Some lines are fixed for certain types of devices while some can be multiplexed between various devices. The APIC controller translates the IRQ number into the Interrupt Vector for the CPU’s table. Basically based on the IRQ line that signalled it, the APIC gives an INT (e.g., INT 0eh) to the CPU.When a CPU is finished handling an interrupt, it tells the APIC it’s ok to resume sending interrupts.If conflict – Plug and Play solves it. Also, interrupts have priorities.
18Useful readings Linux Device Drivers, 3rd edition Chapter 10 – Interrupt HandlingThe Linux Kernel Module Programming guideChapter 12 – Interrupt HandlersUnderstanding the Linux KernelChapter 4 – Interrupts and ExceptionsConsult LXR – Deep understanding of Linux source code and data structures involved