Interrupts and bottom halves
In the last post in interrupts we discussed some of the design issued to be considered while writing an interrupt service routine. Two main things which came up were: Interrupt Service Routine should be as quick as possible and perform some reasonable amount of work. These two requirement are mutually contradicting. How do we achieve these two goals?
To do so, we divide the ISR into two parts called as halves. First one is top half which does the minimum required functions of for handling given interrupt and schedules the other half which is called as bottom half which does the bulk of the task later.
Bottom halves are required because as we know when ISR executes, it disables all other interrupts on running processor and same interrupt on all processors. To increase the response time and throughput of the system, we need to finish ISR as soon as possible.
Let’s take an example : A packet arrives at network card. Card has to generate an interrupt to kernel saying it has a packet. Now above dichotomy comes into picture. If kernel starts to process the whole packet in the ISR, network card will not be able to receive any packet till ISR if finish.
So in top of half of the ISR, kernel just acknowledges the reception of packet, copies it in main memory and network is again ready for the new packet.Rest of the processing is done by the bottom half at later point of time.
There are some considerations we should keep in mind while delegating work to bottom half:
If work is time sensitive, hardware specific or needs all other interrupts to be disable while being done, do it in interrupts top half, rest all can be delegated to bottom half.
Bottom halves are implemented using: Tasklets, softirqs or works queues.
Now let us look into some of the very basic questions asked about interrupts.
Difference between exception, trap and interrupt
Trap is usually called as software interrupts also. It is specifically added by the programmer using instruction to transfer control to a given handler. Best example is INT instruction. As it is added explicitly by the programmer, we always know when trap will occur. Trap and simple function call are same except that trap stores registers on stack and we need to do IRET in order to return from it.
Exceptions occur when program as encounter a conditions which is not as per the expectation. Exceptions are usually called as automatically generated traps, however there is no specific instruction associated with exceptions. Common causes of exceptions are divide by zero, executing illegal op-code or illegal memory access, break point exceptions, overflow exception etc. As soon as any condition above is encountered, current execution is suspended and control passes to exception handler. Exception handler decides what to do like aborting the process or restarting it etc.
Interrupts do not have anything to do with currently executing instruction. These are external to the process currently being executed. These are generated by like receiving a packet on network card, pressing a key on keyboard, serial ports, parallel ports, timers etc. CPU after executing the current instruction, passed control to Interrupt handler and once interrupt handler finishes, control returns back to the next instruction of the program which was interrupted.