Operating Systems – CSCI 402
Interrupt Handling – Overview Interrupt Handling
Deferred Work
Directed Processing
APCs Signals
Interrupts
Threads
Thread preemption
4
321 0
Copyright ý . Systems – CSCI 402
Deferred Work
Interrupt handlers run with interrupts masked (up to its interrupt priority level)
both when executed in interrupt context or thread context may interfere with handling of other interrupts
they must run to completion (but may be interrupted by a higher priority interrupt)
it must complete quickly
What to do if an interrupt handler has a lot of work to be done?
only do what you must do inside the interrupt handler
defer most of the work to be done after the interrupt handler returns
5
321 0
Copyright ý . Systems – CSCI 402
Deferred Work
Ex: network packet processing
TCP header processing can take a long time
not suitable to do them in a interrupt handler
Solution
do minimal work now
do rest later without interrupts masked
Memory
How?
I/O Management Network / TCP
Driver
NIC
Copyright ý . Cheng
hdr
data
interrupt DMA
6
321 0
Deferred Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
} }
Operating Systems – CSCI 402
Kernel stack frames
Ex: interrupting a kernel thread
Current thread¡¯s kernel stack
user thread context
321 0
stack allows us to return to previous context
7
Copyright ý . Systems – CSCI 402
Deferred Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
} }
void KeyboardInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
Current thread¡¯s kernel stack
kernel thread context
user thread context
321 0
Interrupt #3¡¯s handler frame
Kernel stack frames
stack allows us to return to previous context
8
Copyright ý . Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
}
void DiskInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
}
interrupt #3 handler context
kernel thread context
user thread context
321 0
Operating Systems – CSCI 402
Interrupt #7¡¯s handler frame
Interrupt #3¡¯s handler frame
Kernel stack frames
Current thread¡¯s kernel stack
stack allows us to return to previous context
9
Copyright ý . Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
}
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work();
interrupt #7 handler context
interrupt #3 handler context
kernel thread context
user thread context
321 0
void NetworkInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
Current thread¡¯s kernel stack
Operating Systems – CSCI 402
Interrupt #23¡¯s handler frame
Interrupt #7¡¯s handler frame
Interrupt #3¡¯s handler frame
Kernel stack frames
} }
stack allows us to return to previous context
10
Copyright ý . Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
}
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work();
interrupt #7 handler context
interrupt #3 handler context
kernel thread context
user thread context
321 0
void NetworkInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
Current thread¡¯s kernel stack
Operating Systems – CSCI 402
Interrupt #7¡¯s handler frame
Interrupt #3¡¯s handler frame
Kernel stack frames
} }
stack allows us to return to previous context
11
Copyright ý . Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
}
void DiskInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
}
interrupt #3 handler context
kernel thread context
user thread context
321 0
Operating Systems – CSCI 402
Interrupt #7¡¯s handler frame
Interrupt #3¡¯s handler frame
Kernel stack frames
Current thread¡¯s kernel stack
stack allows us to return to previous context
12
Copyright ý . Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
}
void DiskInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
}
interrupt #3 handler context
kernel thread context
user thread context
321 0
Operating Systems – CSCI 402
Interrupt #3¡¯s handler frame
Kernel stack frames
Current thread¡¯s kernel stack
stack allows us to return to previous context
13
Copyright ý . Systems – CSCI 402
Deferred Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
} }
void KeyboardInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
Current thread¡¯s kernel stack
kernel thread context
user thread context
321 0
Interrupt #3¡¯s handler frame
Kernel stack frames
stack allows us to return to previous context
14
Copyright ý . Systems – CSCI 402
Deferred Processing
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev](); // call appropriate handler
if (PreviousContext == ThreadContext) {
UnMaskInterrupts();
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
} }
void KeyboardInterruptHandler() {
// deal with interrupt
// do minimal work
…
EnQueue(WorkQueue, MoreWork);
}
Ex: interrupting a kernel thread
Current thread¡¯s kernel stack
kernel thread context
user thread context
321 0
Kernel stack frames
stack allows us to return to previous context
15
Copyright ý . Cheng
hardware
Operating Systems – CSCI 402
Windows Interrupt Priority Levels
31
High
30
Power fail
29
Inter-processor
28
Clock
.
.
.
.
.
.
4
Device 2
3
Device 1
2
DPC
1
APC
0
Thread
Windows handles deferred work in a special interrupt context
DPC (deferred procedure call) is a software interrupt
software
16
321 0
Copyright ý . Systems – CSCI 402
Deferred Procedure Calls
void InterruptHandler( ) {
// deal with interrupt, IPL already ¡Ý 3
…
QueueDPC(MoreWork);
/* requests an asynchronous DPC interrupt */
}
void DPCHandler( … ) {
while(!Empty(DPCQueue)) {
Work = DeQueue(DPCQueue);
Work(); }
}
17
321 0
Copyright ý . Systems – CSCI 402
Software Interrupt Threads
Linux handles deferred work in a special kernel thread
this kernel thread is scheduled like any other kernel thread
void InterruptHandler( ) {
// deal with interrupt
…
EnQueue(WorkQueue, MoreWork);
SetEvent(Work);
}
void SoftwareInterruptThread() {
while(TRUE) {
WaitEvent(Work)
while(!Empty(WorkQueue)) {
Work = DeQueue(WorkQueue);
Work(); }
} }
18
321 0
Copyright ý . Systems – CSCI 402
Thread Preemption
running
runnable
OS
Scheduler
INT
19
321 0
Copyright ý . Systems – CSCI 402
Preemption: User-Level Only
Non-preemptive kernel
preempt only threads running in user mode
if clock-interrupt happens, just set a global flag
void ClockHandler( ) {
// deal with clock
// interrupt
…
if (TimeSliceOver())
ShouldReschedule = 1;
}
20
321 0
Copyright ý . : User-Level Only
If interrupted a user thread
void TopLevelInterruptHandler(int dev) {
InterruptVector[dev]();
if (PreviousMode == UserMode) {
// the clock interrupted user-mode code
} }
If interrupted a kernel thread
void TopLevelTrapHandler(…) {
SpecificTrapHandler();
if (ShouldReschedule) {
/* the time slice expired
while the thread was
in kernel mode */
Reschedule();
}
}
321 0
Operating Systems – CSCI 402
if (ShouldReschedule)
Reschedule();
Reschedule() puts the calling thread on the run queue
then call thread_switch() to give up the processor
The work of rescheduling is deferred
21
Copyright ý . Systems – CSCI 402
Preemption: Full (i.e., Preemptive Kernel)
Preemptive kernel
preemption can happen for a kernel thread
if clock-interrupt happens, setup the kernel thread to give up the processor when the processor is about to return to the thread¡¯s context
how?
e.g., in Windows, add the Reschedule() function to the DPC queue and invoke a DPC interrupt
void ClockInterruptHandler( ) {
// deal with clock interrupt
if (TimeSliceOver()) {
QueueDPC(Reschedule);
/* requests an asynchronous DPC interrupt */
}
}
22
321 0
Copyright ý . Systems – CSCI 402
Interrupt Handling – Overview Interrupt Handling
Deferred Work
Directed Processing
APCs Signals
Interrupts
Threads
Thread preemption
23
321 0
Copyright ý . : Unix
Directed Processing
perform given action in context of a particular thread in user mode
e.g.,
generated by hardware and needs to be delievered to the user process to invoke a singal handler
APC (Asynchronous Procedure Calls): Windows
roughly same thing, but also may be done in privileged mode provides a general callback mechanism for the kernel and for user processes
thus, APC is more general than Unix signals
software
Operating Systems – CSCI 402
2
DPC
1
APC
0
Thread
Windows Interrupt Priority Levels
321 0
24
Copyright ý . Systems – CSCI 402
Invoking the Signal Handler
Basic idea is to set up the user stack so that the handler is called as a subroutine and so that when it returns, normal execution of the thread may continue
Complications:
saving and restoring registers
must first save all registers and later on restore all of them signal mask
must block the signal and later on unblock the signal
therefore, when the signal handler returns, it needs to return to some code that restores all the registers, unblocks the signal, then return to the interrupted code
25
321 0
Copyright ý . P
User Stack X
Operating Systems – CSCI 402
Invoking the Signal Handler (1)
Main Line
func(int a1,
int a2) {
int i, j = 2;
for (i=a1;
i