The interrupt structure in a typical personal computer system is depicted in the accompanying Figure. Interrupts function in hardware in the manner described below.
If the operating system has enabled interrupts, an I/O device will produce an interrupt when the given task is complete. In order to accomplish this, it asserts a signal on a bus line that is designated for it. The interrupt controller chip on the motherboard detects this signal and makes a decision based on it.
If no other interrupts are pending, the interrupt controller processes the interrupt immediately.
If another one is in progress, or another device has made a simultaneous request on a higher-priority interrupt request line on the bus, the device is just ignored for the moment. In this case, it continues to assert an interrupt signal on the bus until it is serviced by the CPU.
To handle the interrupt, the controller puts a number on the address lines specifying which device wants attention and asserts a signal that interrupts the CPU.
The interrupt signal causes the CPU to stop what it is doing and start doing something else.
The number on the address lines is used as an index into a table called the interrupt vector to fetch a new program counter. This program counter points to the start of the corresponding interrupt service procedure.
Typically traps and interrupts use the same mechanism from this point on, and frequently share the same interrupt vector.
The location of the interrupt vector can be hardwired into the machine or it can be anywhere in memory, with a CPU register (loaded by the operating system) pointing to its origin.
Shortly after it starts running, the interrupt service procedure acknowledges the interrupt by writing a certain value to one of the interrupt controller’s I/O ports. This acknowledgment tells the controller that it is free to issue another interrupt. By having the CPU delay this acknowledgment until it is ready to handle the next interrupt, race conditions involving multiple almost simultaneous interrupts can be avoided.
As an aside, some (older) computers do not have a centralized interrupt controller chip, so each device controller requests its own interrupts.
The hardware always saves certain information before starting the service procedure. Which information is saved and where it is saved varies greatly from CPU to CPU. As a bare minimum, the program counter must be saved, so the interrupted process can be restarted. At the other extreme, all the visible registers and a large number of internal registers may be saved as well.
If the kernel stack is used, there is a much better chance of the stack pointer being legal and pointing to a pinned page. However, switching into kernel mode may require changing MMU contexts and will probably invalidate most or all of the cache and TLB. Reloading all of these, statically or dynamically will increase the time to process an interrupt and thus waste CPU time.
Another problem is caused by the fact that most modern CPUs are heavily pipelined and often superscalar (internally parallel). In older systems, after each instruction was finished executing, the microprogram or hardware checked to see if there was an interrupt pending. If so, the program counter and PSW were pushed onto the stack and the interrupt sequence began. After the interrupt handler ran, the reverse process took place, with the old PSW and program counter popped from the stack and the previous process continued.
An interrupt that leaves the machine in a well-defined state is called a precise interrupt (Walker and Cragon, 1995). Such an interrupt has four properties:
- The PC (Program Counter) is saved in a known place.
- All instructions before the one pointed to by the PC have been fully executed.
- No instruction beyond the one pointed to by the PC has been executed.
- The execution state of the instruction pointed to by the PC is known.
Note that there is no prohibition on instructions beyond the one pointed to by the PC from starting. It is just that any changes they make to registers or memory must be undone before the interrupt happens.
It is permitted that the instruction pointed to has been executed. It is also permitted that it has not been executed. However, it must be clear which case applies. Often, if the interrupt is an I/O interrupt, the instruction will not yet have started. However, if the interrupt is really a trap or page fault, then the PC generally points to the instruction that caused the fault so it can be restarted later.
An interrupt that does not meet these requirements is called an imprecise interrupt and makes life extremely unpleasant for the operating system writer, who now has to figure out what has happened and what still has to happen.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.