I think we can just let the red/black tree thing rest now Interlude: What does happen if you make a mistake? Let's make a mistake and find out! Polling vs. interrupts: Like USB vs. PS/2 How often? /proc/interrupts IRQ Lines: Different devices will have different interrupt numbers Interrupt interrupts the processor - So we finish with the interrupt handler QUICKLY - We can set a timer to do other stuff later request_irq function: int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev) Demo time: I have a few of these around, in various states of disrepair irq: irq number handler: Function to call when the interrupt happens Flags: IRQF_DISABLED (disable all others while in handler, bad form) IRQF_SAMPLE_RANDOM (interrupts can be considered in random pool, security) IRQF_TIMER (It's an interrupt from the system timer) IRQF_SHARED (IRQ can have multiple handlers) name: ASCII name for the handler dev: For shared interrupt lines, a unique ID - Can be a memory address free_irq: Same thing in reverse sort of with less parameters - It's good to call it Interrupt Context: NOT associated with any process Can't call sleep, or any function that uses sleep - kmalloc can sleep Special interrupt stack - And it's small, maybe 4K but this depends - Assume it's small - Accessing variables global to your interrupt handler is ok Disabling interrupts: local_irq_disable(); local_irq_enable(); I didn't try this, but I think it would be hard to totally disable these They're disabled for the current processor only There used to be a way to totally disable them - Removed to make sure nobody would use it - Guess we can't break the keyboard Better to save/restore state Another way: void disable_irq(unsigned int irq); void disable_irq_nosync(unsigned int irq); void enable_irq(unsigned int irq); void synchronize_irq(unsigned int irq); Let's try it! Maybe we'll learn something There's a nice list of good irq-control functions in the book (page 130) Reminder: System calls do interrupt 0x80 This is called the "top half". The "bottom half" handles work you don't want to do in interrupt context Lengthy top-half is frowned upon, but is somewhat more acceptable with multi-core - Can still gum up the works (how bad?) - Linux runs on single-core systems! - Remember: Not everything is x86, or even ARM - NetBSD vs. FreeBSD top vs. bottom half is pretty universal