Interrupt priority level

From Wikipedia, the free encyclopedia

The interrupt priority level (IPL) is a part of the current system interrupt state, which indicates the interrupt requests that will currently be accepted. The IPL may be indicated in hardware by the registers in a Programmable Interrupt Controller, or in software by a bitmask or integer value.

[edit] Overview

An integer based IPL may be as small as a single bit, with just two values: 0 (all interrupts enabled) or 1 (all interrupts disabled). However, some architectures permit a greater range of values, where each value enables interrupt requests that specify a higher level, while blocking ones from the same or lower level.

Assigning different priorities to interrupt requests can be useful in trying to balance system throughput versus interrupt latency: some kinds of interrupts need to be responded to more quickly than others, but the amount of processing might not be large, so it makes sense to assign a higher priority to that kind of interrupt.

Control of interrupt level was also used to synchronize access to kernel data structures. Thus, the level-3 scheduler interrupt handler would temporarily raise IPL to 7 before accessing any actual scheduler data structures, then lower back to 3 before actually switching process contexts. However, it was not allowed for an interrupt handler to lower IPL below that at which it was entered, since to do so could destroy the integrity of the synchronization system.

Of course, multiprocessor systems add their own complications, which are not addressed here.

Regardless of what the hardware might support, typical UNIX-type systems only make use of two levels: the minimum (all interrupts enabled) and the maximum (all interrupts disabled).

[edit] VAX IPLs

As an example of one of the more elaborate IPL-handling systems ever deployed, the VAX computer and associated VMS operating system supported 32 priority levels, from 0 to 31. Priorities 16 and above were for requests from external hardware, while values below 16 were available for software interrupts (used internally by the operating system to schedule its own activities). Not all values were actually used, but here are some of the more important ones:

  • level 31 was for the "power-fail" interrupt.
  • level 24 was for the clock interrupt. Note this was a higher priority than I/O interrupts.
  • levels 20-23 were used for I/O devices.
  • levels 8-11 were used for fork interrupts. When a driver received a device interrupt (priority 20-23), it was supposed to do as little processing as possible at such a high priority; instead, if any time-consuming operations needed to be done, these were to be deferred by requesting a software interrupt in the 8-11 range; when this interrupt was triggered, the further processing would resume. Similar to this are "bottom halves" and their successors in the Linux kernel.
  • level 7 was used to synchronize access to the process scheduler data structures.
  • level 4 was used for I/O post-processing tasks--that is, final completion of a QIO request including returning results to the application process.
  • level 3 was used for the process rescheduling interrupt. Any code executing at higher interrupt levels was not allowed to assume that there was a current process context (since a process reschedule might be in progress). In particular, page faults were not allowed at this or higher levels.
  • level 2 was used to synchronize access to per-process data structures. Any time the kernel needed access to a process context, it sent that process a special kernel AST which executed in the process context at IPL 2.
  • level 0 was the normal level for execution of non-interrupt code, including ordinary application code.

[edit] See also