1. Lab 8: Interrupts and Device Drivers
Advanced Operating Systems
Zubair Nabi
zubair.nabi@itu.edu.pk
March 28, 2013
2. Recap of Lab 5: Extraordinary events
Events that break normal processor flow, to return control to the
kernel:
1
A device signals that it needs attention (e.g. Timer): Interrupt
2
A user program does something illegal (e.g. divide by zero):
Exception
3
A user program asks the kernel for a service: System call
3. Recap of Lab 5: Extraordinary events
Events that break normal processor flow, to return control to the
kernel:
1
A device signals that it needs attention (e.g. Timer): Interrupt
2
A user program does something illegal (e.g. divide by zero):
Exception
3
A user program asks the kernel for a service: System call
4. Recap of Lab 5: Extraordinary events
Events that break normal processor flow, to return control to the
kernel:
1
A device signals that it needs attention (e.g. Timer): Interrupt
2
A user program does something illegal (e.g. divide by zero):
Exception
3
A user program asks the kernel for a service: System call
5. Recap of Lab 5: Extraordinary events
Events that break normal processor flow, to return control to the
kernel:
1
A device signals that it needs attention (e.g. Timer): Interrupt
2
A user program does something illegal (e.g. divide by zero):
Exception
3
A user program asks the kernel for a service: System call
6. Recap of Lab 5: Handling extraordinary events
The operating system must:
1
Save the processor’s registers for future resumption
2
Set up system for execution in the kernel
3
Choose a place for the kernel to start execution
4
Retrieve information about the event and call corresponding
interrupt handler
5
All the while, maintain isolation between user processes and the
kernel
7. Recap of Lab 5: Handling extraordinary events
The operating system must:
1
Save the processor’s registers for future resumption
2
Set up system for execution in the kernel
3
Choose a place for the kernel to start execution
4
Retrieve information about the event and call corresponding
interrupt handler
5
All the while, maintain isolation between user processes and the
kernel
8. Recap of Lab 5: Handling extraordinary events
The operating system must:
1
Save the processor’s registers for future resumption
2
Set up system for execution in the kernel
3
Choose a place for the kernel to start execution
4
Retrieve information about the event and call corresponding
interrupt handler
5
All the while, maintain isolation between user processes and the
kernel
9. Recap of Lab 5: Handling extraordinary events
The operating system must:
1
Save the processor’s registers for future resumption
2
Set up system for execution in the kernel
3
Choose a place for the kernel to start execution
4
Retrieve information about the event and call corresponding
interrupt handler
5
All the while, maintain isolation between user processes and the
kernel
10. Recap of Lab 5: Handling extraordinary events
The operating system must:
1
Save the processor’s registers for future resumption
2
Set up system for execution in the kernel
3
Choose a place for the kernel to start execution
4
Retrieve information about the event and call corresponding
interrupt handler
5
All the while, maintain isolation between user processes and the
kernel
11. Recap of Lab 5: Handling extraordinary events
The operating system must:
1
Save the processor’s registers for future resumption
2
Set up system for execution in the kernel
3
Choose a place for the kernel to start execution
4
Retrieve information about the event and call corresponding
interrupt handler
5
All the while, maintain isolation between user processes and the
kernel
12. Recap of Lab 5: Handling extraordinary events (2)
• Need hardware support
• On the x86, system calls generate an interrupt via the int
instruction
• The same mechanism for handling interrupts is used for handling
system calls and exceptions
• Traps are caused by the current running process
• Interrupts are caused by devices
• Can happen concurrently
13. Recap of Lab 5: Handling extraordinary events (2)
• Need hardware support
• On the x86, system calls generate an interrupt via the int
instruction
• The same mechanism for handling interrupts is used for handling
system calls and exceptions
• Traps are caused by the current running process
• Interrupts are caused by devices
• Can happen concurrently
14. Recap of Lab 5: Handling extraordinary events (2)
• Need hardware support
• On the x86, system calls generate an interrupt via the int
instruction
• The same mechanism for handling interrupts is used for handling
system calls and exceptions
• Traps are caused by the current running process
• Interrupts are caused by devices
• Can happen concurrently
15. Recap of Lab 5: Handling extraordinary events (2)
• Need hardware support
• On the x86, system calls generate an interrupt via the int
instruction
• The same mechanism for handling interrupts is used for handling
system calls and exceptions
• Traps are caused by the current running process
• Interrupts are caused by devices
• Can happen concurrently
16. Recap of Lab 5: Handling extraordinary events (2)
• Need hardware support
• On the x86, system calls generate an interrupt via the int
instruction
• The same mechanism for handling interrupts is used for handling
system calls and exceptions
• Traps are caused by the current running process
• Interrupts are caused by devices
• Can happen concurrently
17. Recap of Lab 5: Handling extraordinary events (2)
• Need hardware support
• On the x86, system calls generate an interrupt via the int
instruction
• The same mechanism for handling interrupts is used for handling
system calls and exceptions
• Traps are caused by the current running process
• Interrupts are caused by devices
• Can happen concurrently
18. Recap of Lab 5: trap
• Gets passed struct trapframe *tf
• Checks tf->trapno to decide if it was called for a system call
(T_SYSCALL) or a hardware interrupt or an exception
• In case of:
1 System call, it invokes syscall
2
3
Hardware interrupt, it calls the hardware interrupt controller
Exception, it prints the details and kills the user process
19. Recap of Lab 5: trap
• Gets passed struct trapframe *tf
• Checks tf->trapno to decide if it was called for a system call
(T_SYSCALL) or a hardware interrupt or an exception
• In case of:
1 System call, it invokes syscall
2
3
Hardware interrupt, it calls the hardware interrupt controller
Exception, it prints the details and kills the user process
20. Recap of Lab 5: trap
• Gets passed struct trapframe *tf
• Checks tf->trapno to decide if it was called for a system call
(T_SYSCALL) or a hardware interrupt or an exception
• In case of:
1 System call, it invokes syscall
2
3
Hardware interrupt, it calls the hardware interrupt controller
Exception, it prints the details and kills the user process
21. Recap of Lab 5: trap
• Gets passed struct trapframe *tf
• Checks tf->trapno to decide if it was called for a system call
(T_SYSCALL) or a hardware interrupt or an exception
• In case of:
1 System call, it invokes syscall
2
3
Hardware interrupt, it calls the hardware interrupt controller
Exception, it prints the details and kills the user process
22. Recap of Lab 5: trap
• Gets passed struct trapframe *tf
• Checks tf->trapno to decide if it was called for a system call
(T_SYSCALL) or a hardware interrupt or an exception
• In case of:
1 System call, it invokes syscall
2
3
Hardware interrupt, it calls the hardware interrupt controller
Exception, it prints the details and kills the user process
23. Interrupts
• Examples of interrupts: Pressing a key on the keyboard, storing
data on disk etc.
• Hardware on the motherboard signals the CPU whenever a
device needs attention
• Devices need to be programmed to generate interrupts
• Interrupts must be assigned to a CPU for handling
24. Interrupts
• Examples of interrupts: Pressing a key on the keyboard, storing
data on disk etc.
• Hardware on the motherboard signals the CPU whenever a
device needs attention
• Devices need to be programmed to generate interrupts
• Interrupts must be assigned to a CPU for handling
25. Interrupts
• Examples of interrupts: Pressing a key on the keyboard, storing
data on disk etc.
• Hardware on the motherboard signals the CPU whenever a
device needs attention
• Devices need to be programmed to generate interrupts
• Interrupts must be assigned to a CPU for handling
26. Interrupts
• Examples of interrupts: Pressing a key on the keyboard, storing
data on disk etc.
• Hardware on the motherboard signals the CPU whenever a
device needs attention
• Devices need to be programmed to generate interrupts
• Interrupts must be assigned to a CPU for handling
27. Handing interrupts on multi-processors
Two parts of handling interrupts on multi-processors
1
A method to route interrupts to processors (I/O APIC – Advanced
Programmable Interrupt Controller, ioapic.c)
2
A per CPU interrupt controller to handle interrupts (Local APIC,
lapic.c)
The OS needs to program both the IOAPIC and the LAPIC
28. Handing interrupts on multi-processors
Two parts of handling interrupts on multi-processors
1
A method to route interrupts to processors (I/O APIC – Advanced
Programmable Interrupt Controller, ioapic.c)
2
A per CPU interrupt controller to handle interrupts (Local APIC,
lapic.c)
The OS needs to program both the IOAPIC and the LAPIC
29. Handing interrupts on multi-processors
Two parts of handling interrupts on multi-processors
1
A method to route interrupts to processors (I/O APIC – Advanced
Programmable Interrupt Controller, ioapic.c)
2
A per CPU interrupt controller to handle interrupts (Local APIC,
lapic.c)
The OS needs to program both the IOAPIC and the LAPIC
30. IOAPIC
• Interrupts are generated by the APIC labelled from IRQ0 to
IRQ16 or IRQ24
• A device enables particular interrupts within the IOAPIC table and
specifies which processor they should be routed to
• For instance, the keyboard interrupt is routed to CPU0 while disk
interrupts are routed to CPU(n − 1), where n is the number of
CPUs
• Every CPU decides whether it wants to receive interrupts. For
instance, scheduler() disables all interrupts
31. IOAPIC
• Interrupts are generated by the APIC labelled from IRQ0 to
IRQ16 or IRQ24
• A device enables particular interrupts within the IOAPIC table and
specifies which processor they should be routed to
• For instance, the keyboard interrupt is routed to CPU0 while disk
interrupts are routed to CPU(n − 1), where n is the number of
CPUs
• Every CPU decides whether it wants to receive interrupts. For
instance, scheduler() disables all interrupts
32. IOAPIC
• Interrupts are generated by the APIC labelled from IRQ0 to
IRQ16 or IRQ24
• A device enables particular interrupts within the IOAPIC table and
specifies which processor they should be routed to
• For instance, the keyboard interrupt is routed to CPU0 while disk
interrupts are routed to CPU(n − 1), where n is the number of
CPUs
• Every CPU decides whether it wants to receive interrupts. For
instance, scheduler() disables all interrupts
33. IOAPIC
• Interrupts are generated by the APIC labelled from IRQ0 to
IRQ16 or IRQ24
• A device enables particular interrupts within the IOAPIC table and
specifies which processor they should be routed to
• For instance, the keyboard interrupt is routed to CPU0 while disk
interrupts are routed to CPU(n − 1), where n is the number of
CPUs
• Every CPU decides whether it wants to receive interrupts. For
instance, scheduler() disables all interrupts
34. LAPIC
• Each CPU has its own LAPIC
• xv6 programs the LAPIC using lapicinit()
35. LAPIC
• Each CPU has its own LAPIC
• xv6 programs the LAPIC using lapicinit()
36. Example: Timer interrupt
• The kernel uses timer interrupts to get a notion of time and to
make scheduling decisions
• A value of 100 timer ticks is used by default which is high enough
to allow interactivity and low enough not to lead to a live lock
• This value is set in lapicinit() and IRQ_TIMER is mapped
to IRQ0
• IRQ_TIMER corresponds to interrupt number 32
• In trap(), for interrupt number 32, the timer tick is incremented
and processes sleeping on it are woken up
37. Example: Timer interrupt
• The kernel uses timer interrupts to get a notion of time and to
make scheduling decisions
• A value of 100 timer ticks is used by default which is high enough
to allow interactivity and low enough not to lead to a live lock
• This value is set in lapicinit() and IRQ_TIMER is mapped
to IRQ0
• IRQ_TIMER corresponds to interrupt number 32
• In trap(), for interrupt number 32, the timer tick is incremented
and processes sleeping on it are woken up
38. Example: Timer interrupt
• The kernel uses timer interrupts to get a notion of time and to
make scheduling decisions
• A value of 100 timer ticks is used by default which is high enough
to allow interactivity and low enough not to lead to a live lock
• This value is set in lapicinit() and IRQ_TIMER is mapped
to IRQ0
• IRQ_TIMER corresponds to interrupt number 32
• In trap(), for interrupt number 32, the timer tick is incremented
and processes sleeping on it are woken up
39. Example: Timer interrupt
• The kernel uses timer interrupts to get a notion of time and to
make scheduling decisions
• A value of 100 timer ticks is used by default which is high enough
to allow interactivity and low enough not to lead to a live lock
• This value is set in lapicinit() and IRQ_TIMER is mapped
to IRQ0
• IRQ_TIMER corresponds to interrupt number 32
• In trap(), for interrupt number 32, the timer tick is incremented
and processes sleeping on it are woken up
40. Example: Timer interrupt
• The kernel uses timer interrupts to get a notion of time and to
make scheduling decisions
• A value of 100 timer ticks is used by default which is high enough
to allow interactivity and low enough not to lead to a live lock
• This value is set in lapicinit() and IRQ_TIMER is mapped
to IRQ0
• IRQ_TIMER corresponds to interrupt number 32
• In trap(), for interrupt number 32, the timer tick is incremented
and processes sleeping on it are woken up
41. Device Driver
• A piece of code in the OS that manages a particular device
• Provides interrupt handlers for a device
• Causes a device to perform operations
• Causes a device to generate interrupts
• Non-trivial to write as a driver executes concurrently with the
device that it manages
• Driver also needs to understand the hardware interface of the
device
42. Device Driver
• A piece of code in the OS that manages a particular device
• Provides interrupt handlers for a device
• Causes a device to perform operations
• Causes a device to generate interrupts
• Non-trivial to write as a driver executes concurrently with the
device that it manages
• Driver also needs to understand the hardware interface of the
device
43. Device Driver
• A piece of code in the OS that manages a particular device
• Provides interrupt handlers for a device
• Causes a device to perform operations
• Causes a device to generate interrupts
• Non-trivial to write as a driver executes concurrently with the
device that it manages
• Driver also needs to understand the hardware interface of the
device
44. Device Driver
• A piece of code in the OS that manages a particular device
• Provides interrupt handlers for a device
• Causes a device to perform operations
• Causes a device to generate interrupts
• Non-trivial to write as a driver executes concurrently with the
device that it manages
• Driver also needs to understand the hardware interface of the
device
45. Device Driver
• A piece of code in the OS that manages a particular device
• Provides interrupt handlers for a device
• Causes a device to perform operations
• Causes a device to generate interrupts
• Non-trivial to write as a driver executes concurrently with the
device that it manages
• Driver also needs to understand the hardware interface of the
device
46. Device Driver
• A piece of code in the OS that manages a particular device
• Provides interrupt handlers for a device
• Causes a device to perform operations
• Causes a device to generate interrupts
• Non-trivial to write as a driver executes concurrently with the
device that it manages
• Driver also needs to understand the hardware interface of the
device
47. Example: Disk driver
• In charge of copying data back and forth from the disk
• Data is represented on the disk as a sequence of sectors, each
containing 512-byte blocks
• Sector 0 represents the first 512 bytes, sector 1 the next 512, and
so on
• The OS has a corresponding structure (struct buf) that
maps to one sector
• The data within the OS sector structure is often out of sync with
the disk
• xv6 implements an IDE driver
48. Example: Disk driver
• In charge of copying data back and forth from the disk
• Data is represented on the disk as a sequence of sectors, each
containing 512-byte blocks
• Sector 0 represents the first 512 bytes, sector 1 the next 512, and
so on
• The OS has a corresponding structure (struct buf) that
maps to one sector
• The data within the OS sector structure is often out of sync with
the disk
• xv6 implements an IDE driver
49. Example: Disk driver
• In charge of copying data back and forth from the disk
• Data is represented on the disk as a sequence of sectors, each
containing 512-byte blocks
• Sector 0 represents the first 512 bytes, sector 1 the next 512, and
so on
• The OS has a corresponding structure (struct buf) that
maps to one sector
• The data within the OS sector structure is often out of sync with
the disk
• xv6 implements an IDE driver
50. Example: Disk driver
• In charge of copying data back and forth from the disk
• Data is represented on the disk as a sequence of sectors, each
containing 512-byte blocks
• Sector 0 represents the first 512 bytes, sector 1 the next 512, and
so on
• The OS has a corresponding structure (struct buf) that
maps to one sector
• The data within the OS sector structure is often out of sync with
the disk
• xv6 implements an IDE driver
51. Example: Disk driver
• In charge of copying data back and forth from the disk
• Data is represented on the disk as a sequence of sectors, each
containing 512-byte blocks
• Sector 0 represents the first 512 bytes, sector 1 the next 512, and
so on
• The OS has a corresponding structure (struct buf) that
maps to one sector
• The data within the OS sector structure is often out of sync with
the disk
• xv6 implements an IDE driver
52. Example: Disk driver
• In charge of copying data back and forth from the disk
• Data is represented on the disk as a sequence of sectors, each
containing 512-byte blocks
• Sector 0 represents the first 512 bytes, sector 1 the next 512, and
so on
• The OS has a corresponding structure (struct buf) that
maps to one sector
• The data within the OS sector structure is often out of sync with
the disk
• xv6 implements an IDE driver
54. Example: Disk driver initialization
• ideinit() is invoked by main(), which initializes the disk
driver
1 ideinit() sets up CPU(n − 1) to handle disk interrupts
2 It then makes a call to idewait() to wait for disk 0 to initialize
• It assumes that at least disk 0 is present because the boot loader
and the kernel were obviously loaded from it
3
idewait() polls the status bits of the disk hardware, until
IDE_BSY is clear and IDE_DRDY is set
4
It then checks whether another disk is present
55. Example: Disk driver initialization
• ideinit() is invoked by main(), which initializes the disk
driver
1 ideinit() sets up CPU(n − 1) to handle disk interrupts
2 It then makes a call to idewait() to wait for disk 0 to initialize
• It assumes that at least disk 0 is present because the boot loader
and the kernel were obviously loaded from it
3
idewait() polls the status bits of the disk hardware, until
IDE_BSY is clear and IDE_DRDY is set
4
It then checks whether another disk is present
56. Example: Disk driver initialization
• ideinit() is invoked by main(), which initializes the disk
driver
1 ideinit() sets up CPU(n − 1) to handle disk interrupts
2 It then makes a call to idewait() to wait for disk 0 to initialize
• It assumes that at least disk 0 is present because the boot loader
and the kernel were obviously loaded from it
3
idewait() polls the status bits of the disk hardware, until
IDE_BSY is clear and IDE_DRDY is set
4
It then checks whether another disk is present
57. Example: Disk driver initialization
• ideinit() is invoked by main(), which initializes the disk
driver
1 ideinit() sets up CPU(n − 1) to handle disk interrupts
2 It then makes a call to idewait() to wait for disk 0 to initialize
• It assumes that at least disk 0 is present because the boot loader
and the kernel were obviously loaded from it
3
idewait() polls the status bits of the disk hardware, until
IDE_BSY is clear and IDE_DRDY is set
4
It then checks whether another disk is present
58. Example: Disk driver initialization
• ideinit() is invoked by main(), which initializes the disk
driver
1 ideinit() sets up CPU(n − 1) to handle disk interrupts
2 It then makes a call to idewait() to wait for disk 0 to initialize
• It assumes that at least disk 0 is present because the boot loader
and the kernel were obviously loaded from it
3
idewait() polls the status bits of the disk hardware, until
IDE_BSY is clear and IDE_DRDY is set
4
It then checks whether another disk is present
59. Example: Disk driver initialization
• ideinit() is invoked by main(), which initializes the disk
driver
1 ideinit() sets up CPU(n − 1) to handle disk interrupts
2 It then makes a call to idewait() to wait for disk 0 to initialize
• It assumes that at least disk 0 is present because the boot loader
and the kernel were obviously loaded from it
3
idewait() polls the status bits of the disk hardware, until
IDE_BSY is clear and IDE_DRDY is set
4
It then checks whether another disk is present
60. Buffer cache
• The buffer cache is a linked list of struct buf in memory
• It holds cached copies of disk blocks
• Uses iderw(struct buf *b) to read/write a buffer from/to
the disk
• If B_DIRTY is set, it writes b to disk
• If B_VALID is not set, it reads b from disk
61. Buffer cache
• The buffer cache is a linked list of struct buf in memory
• It holds cached copies of disk blocks
• Uses iderw(struct buf *b) to read/write a buffer from/to
the disk
• If B_DIRTY is set, it writes b to disk
• If B_VALID is not set, it reads b from disk
62. Buffer cache
• The buffer cache is a linked list of struct buf in memory
• It holds cached copies of disk blocks
• Uses iderw(struct buf *b) to read/write a buffer from/to
the disk
• If B_DIRTY is set, it writes b to disk
• If B_VALID is not set, it reads b from disk
63. Buffer cache
• The buffer cache is a linked list of struct buf in memory
• It holds cached copies of disk blocks
• Uses iderw(struct buf *b) to read/write a buffer from/to
the disk
• If B_DIRTY is set, it writes b to disk
• If B_VALID is not set, it reads b from disk
64. Buffer cache
• The buffer cache is a linked list of struct buf in memory
• It holds cached copies of disk blocks
• Uses iderw(struct buf *b) to read/write a buffer from/to
the disk
• If B_DIRTY is set, it writes b to disk
• If B_VALID is not set, it reads b from disk
65. iderw
• Disk accesses take milliseconds of time therefore polling is not an
option
• iderw keeps the list of pending disk requests in a queue
(idequeue) and uses interrupts to signal whenever a request
has finished
• It adds b to the end of idequeue
• If b is the only buffer in idequeue, it instantly dispatches it to the
disk hardware by calling idestart() which either issues a
read or a write
• The current process is then put to sleep waiting for the operation
on b to be completed
• Once the hardware has completed the operation, it will generate
an interrupt (IRQ_IDE) which will be handled by trap by
invoking ideintr()
66. iderw
• Disk accesses take milliseconds of time therefore polling is not an
option
• iderw keeps the list of pending disk requests in a queue
(idequeue) and uses interrupts to signal whenever a request
has finished
• It adds b to the end of idequeue
• If b is the only buffer in idequeue, it instantly dispatches it to the
disk hardware by calling idestart() which either issues a
read or a write
• The current process is then put to sleep waiting for the operation
on b to be completed
• Once the hardware has completed the operation, it will generate
an interrupt (IRQ_IDE) which will be handled by trap by
invoking ideintr()
67. iderw
• Disk accesses take milliseconds of time therefore polling is not an
option
• iderw keeps the list of pending disk requests in a queue
(idequeue) and uses interrupts to signal whenever a request
has finished
• It adds b to the end of idequeue
• If b is the only buffer in idequeue, it instantly dispatches it to the
disk hardware by calling idestart() which either issues a
read or a write
• The current process is then put to sleep waiting for the operation
on b to be completed
• Once the hardware has completed the operation, it will generate
an interrupt (IRQ_IDE) which will be handled by trap by
invoking ideintr()
68. iderw
• Disk accesses take milliseconds of time therefore polling is not an
option
• iderw keeps the list of pending disk requests in a queue
(idequeue) and uses interrupts to signal whenever a request
has finished
• It adds b to the end of idequeue
• If b is the only buffer in idequeue, it instantly dispatches it to the
disk hardware by calling idestart() which either issues a
read or a write
• The current process is then put to sleep waiting for the operation
on b to be completed
• Once the hardware has completed the operation, it will generate
an interrupt (IRQ_IDE) which will be handled by trap by
invoking ideintr()
69. iderw
• Disk accesses take milliseconds of time therefore polling is not an
option
• iderw keeps the list of pending disk requests in a queue
(idequeue) and uses interrupts to signal whenever a request
has finished
• It adds b to the end of idequeue
• If b is the only buffer in idequeue, it instantly dispatches it to the
disk hardware by calling idestart() which either issues a
read or a write
• The current process is then put to sleep waiting for the operation
on b to be completed
• Once the hardware has completed the operation, it will generate
an interrupt (IRQ_IDE) which will be handled by trap by
invoking ideintr()
70. iderw
• Disk accesses take milliseconds of time therefore polling is not an
option
• iderw keeps the list of pending disk requests in a queue
(idequeue) and uses interrupts to signal whenever a request
has finished
• It adds b to the end of idequeue
• If b is the only buffer in idequeue, it instantly dispatches it to the
disk hardware by calling idestart() which either issues a
read or a write
• The current process is then put to sleep waiting for the operation
on b to be completed
• Once the hardware has completed the operation, it will generate
an interrupt (IRQ_IDE) which will be handled by trap by
invoking ideintr()
72. ideintr
1
Checks the first buffer in idequeue to find the type of the
operation (read or write)
2
If the operation was a read, it reads the data into the buffer via
insl()
3
It then sets B_VALID and clears B_DIRTY and wakes up any
processes sleeping on b
4
Finally, it dispatches the next buffer from idequeue
73. ideintr
1
Checks the first buffer in idequeue to find the type of the
operation (read or write)
2
If the operation was a read, it reads the data into the buffer via
insl()
3
It then sets B_VALID and clears B_DIRTY and wakes up any
processes sleeping on b
4
Finally, it dispatches the next buffer from idequeue
74. ideintr
1
Checks the first buffer in idequeue to find the type of the
operation (read or write)
2
If the operation was a read, it reads the data into the buffer via
insl()
3
It then sets B_VALID and clears B_DIRTY and wakes up any
processes sleeping on b
4
Finally, it dispatches the next buffer from idequeue
75. ideintr
1
Checks the first buffer in idequeue to find the type of the
operation (read or write)
2
If the operation was a read, it reads the data into the buffer via
insl()
3
It then sets B_VALID and clears B_DIRTY and wakes up any
processes sleeping on b
4
Finally, it dispatches the next buffer from idequeue
76. Modern disk controllers in a real OS
• Most disk controllers typically accept multiple outstanding disk
requests at a time
• They even reorder them to make efficient use of the disk arm
• Conceptually other hardware is very similar to disks
• Network buffers hold packets
• Audio device buffers hold sound samples
• Graphics card buffers hold video data
77. Modern disk controllers in a real OS
• Most disk controllers typically accept multiple outstanding disk
requests at a time
• They even reorder them to make efficient use of the disk arm
• Conceptually other hardware is very similar to disks
• Network buffers hold packets
• Audio device buffers hold sound samples
• Graphics card buffers hold video data
78. Modern disk controllers in a real OS
• Most disk controllers typically accept multiple outstanding disk
requests at a time
• They even reorder them to make efficient use of the disk arm
• Conceptually other hardware is very similar to disks
• Network buffers hold packets
• Audio device buffers hold sound samples
• Graphics card buffers hold video data
79. Modern disk controllers in a real OS
• Most disk controllers typically accept multiple outstanding disk
requests at a time
• They even reorder them to make efficient use of the disk arm
• Conceptually other hardware is very similar to disks
• Network buffers hold packets
• Audio device buffers hold sound samples
• Graphics card buffers hold video data
80. Modern disk controllers in a real OS
• Most disk controllers typically accept multiple outstanding disk
requests at a time
• They even reorder them to make efficient use of the disk arm
• Conceptually other hardware is very similar to disks
• Network buffers hold packets
• Audio device buffers hold sound samples
• Graphics card buffers hold video data
81. Modern disk controllers in a real OS
• Most disk controllers typically accept multiple outstanding disk
requests at a time
• They even reorder them to make efficient use of the disk arm
• Conceptually other hardware is very similar to disks
• Network buffers hold packets
• Audio device buffers hold sound samples
• Graphics card buffers hold video data
82. DMA
• High-bandwidth I/O devices, such as disks, graphics cards,
network cards, etc. often use direct memory access (DMA)
instead of explicit I/O (insl and outsl)
• Via DMA, controllers get direct access to physical memory
• The device driver passes the physical address of the buffer’s data
field to the device, which copies it from/to the main memory
• Once it is done, it generates an interrupt
• As a result of DMA, the CPU is not involved, hence making the
entire process more efficient
83. DMA
• High-bandwidth I/O devices, such as disks, graphics cards,
network cards, etc. often use direct memory access (DMA)
instead of explicit I/O (insl and outsl)
• Via DMA, controllers get direct access to physical memory
• The device driver passes the physical address of the buffer’s data
field to the device, which copies it from/to the main memory
• Once it is done, it generates an interrupt
• As a result of DMA, the CPU is not involved, hence making the
entire process more efficient
84. DMA
• High-bandwidth I/O devices, such as disks, graphics cards,
network cards, etc. often use direct memory access (DMA)
instead of explicit I/O (insl and outsl)
• Via DMA, controllers get direct access to physical memory
• The device driver passes the physical address of the buffer’s data
field to the device, which copies it from/to the main memory
• Once it is done, it generates an interrupt
• As a result of DMA, the CPU is not involved, hence making the
entire process more efficient
85. DMA
• High-bandwidth I/O devices, such as disks, graphics cards,
network cards, etc. often use direct memory access (DMA)
instead of explicit I/O (insl and outsl)
• Via DMA, controllers get direct access to physical memory
• The device driver passes the physical address of the buffer’s data
field to the device, which copies it from/to the main memory
• Once it is done, it generates an interrupt
• As a result of DMA, the CPU is not involved, hence making the
entire process more efficient
86. DMA
• High-bandwidth I/O devices, such as disks, graphics cards,
network cards, etc. often use direct memory access (DMA)
instead of explicit I/O (insl and outsl)
• Via DMA, controllers get direct access to physical memory
• The device driver passes the physical address of the buffer’s data
field to the device, which copies it from/to the main memory
• Once it is done, it generates an interrupt
• As a result of DMA, the CPU is not involved, hence making the
entire process more efficient
87. Dynamic interrupt routing
• In case of xv6 all disk interrupts are routed to CPU(n − 1)
• Real OSes use sophisticated algorithms to dynamically route
interrupts to processors
• The goal is to achieve optimum load balancing while maintaining
good locality
88. Dynamic interrupt routing
• In case of xv6 all disk interrupts are routed to CPU(n − 1)
• Real OSes use sophisticated algorithms to dynamically route
interrupts to processors
• The goal is to achieve optimum load balancing while maintaining
good locality
89. Dynamic interrupt routing
• In case of xv6 all disk interrupts are routed to CPU(n − 1)
• Real OSes use sophisticated algorithms to dynamically route
interrupts to processors
• The goal is to achieve optimum load balancing while maintaining
good locality
90. Reading(s)
• Chapter 3, “Traps, interrupts, and drivers”, section “Code:
Interrupts" onwards from “xv6: a simple, Unix-like teaching
operating system”