interrupts (hardware)

45
Interrupts (Hardware)

Upload: tahlia

Post on 23-Feb-2016

77 views

Category:

Documents


3 download

DESCRIPTION

Interrupts (Hardware). Interrupt Descriptor Table. IDT specified as a segment using the IDTR register . Calling the IRQ handler. Interrupt Context. Exceptions. First 32 IRQ vectors in IDT Correspond to events generated by the CPU Page fault, Divide by zero, invalid instruction, etc - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Interrupts (Hardware)

Interrupts (Hardware)

Page 2: Interrupts (Hardware)

Interrupt Descriptor Table

Slide #2

IDT specified as a segment using the IDTR register

Page 3: Interrupts (Hardware)

Slide #3

Page 4: Interrupts (Hardware)

Calling the IRQ handler

Page 5: Interrupts (Hardware)

Interrupt Context

Page 6: Interrupts (Hardware)

Exceptions

• First 32 IRQ vectors in IDT– Correspond to events generated by the CPU– Page fault, Divide by zero, invalid instruction, etc• Full list in the CPU architecture manuals

– Generally its an “error” or “exception” encountered during CPU instruction execution

• IDT is referenced directly by the CPU– Completely internalized

Page 7: Interrupts (Hardware)

External Interrupts

• Events triggered by devices connected to the system– Network packet arrivals, disk operation completion, timer

updates, etc– Can be mapped to any IRQ vector above the exceptions

• (IRQs 32-255)

• External because they happen outside the CPU– External logic signals CPU and notifies it which handler to

execute– Managed by Interrupt Controller

• Special device included in southbridge

Page 8: Interrupts (Hardware)

Interrupt Controllers

• Translate device IRQ signals to CPU IRQ vectors– Each device has only a single pin

• High = IRQ pending, Low = no IRQ– Interrupt controller maps devices to vectors

• Two x86 controller classes– Legacy: 8259 PIC

• Connected to a set of default I/O ports on CPU– Modern: APIC + IOAPIC

• Memory mapped into each CPUs physical memory– (How?)

• Next generation APIC (x2PIC) accessed via MSRs– Model specific registers – control registers accessed via special instructions

» WRMSR, RDMSR

Page 9: Interrupts (Hardware)

8259 PIC

• Allows the mapping of 8 IRQ pins (from devices) to 8 separate vectors (to CPU)• Assumes continuous numbering• Assign the PIC a vector offset,• Each pin index is added to that offset to calculate the vector

Page 10: Interrupts (Hardware)

8259 Cont’d

• 1 PIC only supports 8 device lines– Often more than 8 devices in a system– Solution: Add more PICs• But x86 CPUs only have 1 INTR input pin

• X86 Solution: – Chain the PICs together (master and slave)• Slave PIC is attached to the 2nd IRQ pin of the master• CPU interfaces directly with master

Page 11: Interrupts (Hardware)

• PC architecture defines common default devices to each PIC input pin• Initially PIC vector offsets set to 32, just above exceptions

Page 12: Interrupts (Hardware)

IRQ ExampleIRQ INT Hardware Device

0 32 Timer

1 33 Keyboard

2 34 PIC Cascading

3 35 Second serial port

4 36 First serial port

6 38 Floppy Disk

8 40 System Clock

10 42 Network Interface

11 43 USB port, sound card

12 44 PS/2 Mouse

13 45 Math Coprocessor

14 46 EIDE first controller

15 47 EIDE second controller

Slide #12

Page 13: Interrupts (Hardware)

APIC

• Problem: PICs don’t support multiple CPUs– Only one INT signal, so only one CPU can receive

interrupts

• SMP required a new solution– APIC + IOAPIC– Idea: Separate the responsibility of the PIC into two

components• APIC = Interfaces with CPU• IOAPIC = Interfaces with devices

Page 14: Interrupts (Hardware)

APIC• Each CPU has its own local APIC

– In charge of keeping track of interrupts bound for its assigned CPU– Since Pentium Pro, the APIC has been implemented in the CPU die

• APIC interfaces with CPUs interrupt pins to invoke correct IDT vector– This is its primary responsibility

• But it does other things as well– Timer – APIC has its own timer device per CPU

• Legacy PC had a separate timer device on the motherboard• Allows each CPU to have its own timer

– Inter-Processor Interrupt – Allows cross CPU communication• 1 CPU can send an interrupt to another one• Why would you want to do this?• How does the APIC do this?

Page 15: Interrupts (Hardware)

ICC bus

• APICs and IOAPICs share a common communication bus• ICC bus: Interrupt Controller Communication Bus

• Handles routing of interrupts to the correct APIC

Page 16: Interrupts (Hardware)

IOAPIC

• Connects devices to ICC bus– Must still translate IRQ pins from devices to vectors – But now must also select destination APIC

• Typically has 24 I/O Redirection Table Registers– Specifies vector # to send to APIC– Specifies which APIC (or group of APICS) can accept

the IRQ• Several methods of specifying APIC addresses

– Allows masking of IRQ pins

Page 17: Interrupts (Hardware)

IO-APIC configuration

• Usually initialized to mirror the PIC configuration– But as architecture diverge from legacy PC, this is

becoming harder– Generally speaking resource discovery is UGLY

• OS then can map IO-APIC entries to which ever vector on whichever CPU they want– This means that IRQ vectors can be reused between

CPUs

Page 18: Interrupts (Hardware)

Interrupt VectorsVector Range Use0-19 Nonmaskable interrupts and exceptions.20-31 Intel-reserved32-127 External interrupts (IRQs)128 System Call exception129-238 External interrupts (IRQs)239 Local APIC timer interrupt240 Local APIC thermal interrupt241-250 Reserved by Linux for future use251-253 Interprocessor interrupts254 Local APIC error interrupt255 Local APIC suprious interrupt

Slide #18

Page 19: Interrupts (Hardware)

IRQ Handling

1. Monitor IRQ lines for raised signals.If multiple IRQs raised, select lowest # IRQ.

2. If raised signal detected1. Converts raised signal into vector (0-255).2. Stores vector in I/O port, allowing CPU to read.3. Sends raised signal to CPU INTR pin.4. Waits for CPU to acknowledge interrupt.5. Kernel runs do_IRQ().6. Clears INTR line.

3. Goto step 1.

Slide #19

Page 20: Interrupts (Hardware)

do_IRQ1. Kernel jumps to entry point in entry.S.2. Entry point saves registers, calls do_IRQ().3. Finds IRQ number in saved %EAX register.4. Looks up IRQ descriptor using IRQ #.5. Acknowledges receipt of interrupt.6. Disables interrupt delivery on line.7. Calls handle_IRQ_event() to run handlers.8. Cleans up and returns.9. Jumps to ret_from_intr().

Slide #20

Page 21: Interrupts (Hardware)

handle_IRQ_event()fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs

*regs, struct irqaction *action){ int ret, retval = 0, status = 0;

if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); do { ret = action->handler(irq, action->dev_id, regs); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); return retval;}

Slide #21

Page 22: Interrupts (Hardware)

Interrupt Handlers

Function kernel runs in response to interrupt.More than one handler can exist per IRQ.

Must run quickly.Resume execution of interrupted code.How to deal with high work interrupts?Ex: network, hard disk

Slide #22

Page 23: Interrupts (Hardware)

Top and Bottom HalvesTop Half

The interrupt handler.Current interrupt disabled, possibly all disabled.Runs in interrupt context, not process context. Can’t sleep.Acknowledges receipt of interrupt.Schedules bottom half to run later.

Bottom HalfRuns in process context with interrupts enabled.Performs most work required. Can sleep.Ex: copies network data to memory buffers.

Slide #23

Page 24: Interrupts (Hardware)

Interrupt Context

Not associated with a process.Cannot sleep: no task to reschedule.current macro points to interrupted process.

Shares kernel stack of interrupted process.Be very frugal in stack usage.

Slide #24

Page 25: Interrupts (Hardware)

Registering a Handler

request_irq()Register an interrupt handler on a given line.

free_irq()Unregister a given interrupt handler.Disable interrupt line if all handlers unregistered.

Slide #25

Page 26: Interrupts (Hardware)

Registering a Handlerint request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),

unsigned long irqflags, const char * devname, void *dev_id)

Slide #26

irqflaqs = SA_INTERRUPT

| SA_SAMPLE_RANDOM

| SA_SHIRQ

Page 27: Interrupts (Hardware)

Writing an Interrupt Handler

Differentiating between devicesPre-2.0: irqCurrent: dev_id

RegistersPointer to registers before interrupt occurred.

Return ValuesIRQ_NONE: Interrupt not for handler.IRQ_HANDLED: Interrupted handled.

Slide #27

irqreturn_t ih(int irq,void *devid,struct pt_regs *r)

Page 28: Interrupts (Hardware)

RTC Handlerirqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs){ spin_lock (&rtc_lock); rtc_irq_data += 0x100; rtc_irq_data &= ~0xff; if (rtc_status & RTC_TIMER_ON) mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);

spin_unlock (&rtc_lock);

/* Now do the rest of the actions */ spin_lock(&rtc_task_lock); if (rtc_callback) rtc_callback->func(rtc_callback->private_data); spin_unlock(&rtc_task_lock); wake_up_interruptible(&rtc_wait);

kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);

return IRQ_HANDLED;}

Slide #28

Page 29: Interrupts (Hardware)

Interrupt ControlDisable/Enable Local Interrupts

local_irq_disable();/* interrupts are disabled */local_irq_enable();

Saving and Restoring IRQ stateUseful when don’t know prior IRQ state.unsigned long flags;local_irq_save(flags);/* interrupts are disabled */local_irq_restore(flags);/* interrupts in original state */

Slide #29

Page 30: Interrupts (Hardware)

Interrupt Control

Disabling Specific InterruptsFor legacy hardware, avoid for shared IRQ lines.disable_irq(irq)enable_irq(irq)

What about other processors?Disable local interrupts + spin lock.We’ll talk about spin locks next time…

Slide #30

Page 31: Interrupts (Hardware)

Bottom Halves

Perform most work required by interrupt.Run in process context with interrupts enabled.

Three forms of deferring workSoftIRQsTaskletsWork Queues

Slide #31

Page 32: Interrupts (Hardware)

SoftIRQs

Statically allocated at compile time.Only 32 softIRQs can exist (only 6 currently used.)struct softirq_action{ void (*action)(struct softirq_action *); void *data;};static struct softirq_action softirq_vec[32];

Tasklets built on SoftIRQs.All tasklets use one SoftIRQ.Dynamically allocated.

Slide #32

Page 33: Interrupts (Hardware)

SoftIRQ Handlers

Prototypevoid softirq_handler(struct softirq_action *)

Callingmy_softirq->action(my_softirq);

Pre-emptionSoftIRQs don’t pre-empt other softIRQs.Interrupt handlers can pre-empt softIRQs.Another softIRQ can run on other CPUs.

Slide #33

Page 34: Interrupts (Hardware)

Executing SoftIRQs

Interrupt handler marks softIRQ.Called raising the softirq.

SoftIRQs checked for execution:In return from hardware interrupt code.In ksoftirq kernel thread.In any code that explicitly checks for softIRQs.

do_softirq()Loops over all softIRQs.

Slide #34

Page 35: Interrupts (Hardware)

Current SoftIRQsSoftIRQ Priority Description

HI 0 High priority tasklets.

TIMER 1 Timer bottom half.

NET_TX 2 Send network packets.

NET_RX 3 Receive network packets.

SCSI 4 SCSI bottom half.

TASKLET 5 Tasklets.

Slide #35

Page 36: Interrupts (Hardware)

Tasklets• Implemented as softIRQs.– Linked list of tasklet_struct objects.

• Two priorities of tasklets:– HI: tasklet_hi_schedule()– TASKLET: tasklet_schedule()

• Scheduled tasklets run via do_softirq()– HI action: tasklet_action()– TASKLET action: tasklet_hi_action()

Slide #36

Page 37: Interrupts (Hardware)

ksoftirqd

SoftIRQs may occur at high frequencies.SoftIRQs may re-raise themselves.Kernel will not handle re-raised softIRQs

immediately in do_softirq().Kernel thread ksoftirq solves problem.

One thread per processor.Runs at lowest priority (nice +19).

Slide #37

Page 38: Interrupts (Hardware)

Work QueuesDefer work into a kernel thread.

Execute in process context.One thread per processor: events/n.Processes can create own threads if needed.

struct workqueue_struct { struct cpu_workqueue_struct cpu_wq[NR_CPUS]; const char *name; struct list_head list; /* Empty if single thread */

};

Slide #38

Page 39: Interrupts (Hardware)

Work Queue Data Structures

Slide #39

worker thread

work_struct

cpu_workqueue_struct 1/CPU

workqueue_struct 1/thread type

work_struct

work_struct1/deferrable function

Page 40: Interrupts (Hardware)

Worker ThreadEach thread runs worker_thread()

1. Marks self as sleeping.2. Adds self to wait queue.3. If linked list of work empty, schedule().4. Else, marks self as running, removes from queue.5. Calls run_workqueue() to perform work.

Slide #40

Page 41: Interrupts (Hardware)

run_workqueue()1. Loops through list of work_structs

struct work_struct { unsigned long pending; struct list_head entry; void (*func)(void *); void *data; void *wq_data; struct timer_list timer;};

2. Retrieves function, func, and arg, data3. Removes entry from list, clears pending4. Invokes function

Slide #41

Page 42: Interrupts (Hardware)

Which Bottom Half to Use?1. If needs to sleep, use work queue.2. If doesn’t need to sleep, use tasklet.3. What about serialization needs?

Bottom Half Context SerializationSoftirq Interrupt NoneTasklet Interrupt Against same tasklet

Work queues Process None

Slide #42

Page 43: Interrupts (Hardware)

Timer Interrupt

Executed HZ times a second.#define HZ 1000 /* <asm/param.h> */Called the tick rate.Time between two interrupts is a tick.Driven by Programmable Interrupt Timer (PIT).

Interrupt handler responsibilitiesUpdating uptime, system time, kernel stats.Rescheduling if current has exhausted time slice.Balancing scheduler runqueues.Running dynamic timers.

Slide #43

Page 44: Interrupts (Hardware)

JiffiesJiffies = number of ticks since boot.

extern unsigned long volatile jiffies;Incremented each timer interrupt.Uptime = jiffies/HZ seconds.Convert for user space: jiffies_to_clock_t()

Comparing jiffies, while avoiding overflow.time_after(a, b): a > btime_before(a,b) a < btime_after_eq(a,b): a >= btime_before_eq(a,b): a <= b

Slide #44

Page 45: Interrupts (Hardware)

Timer Interrupt Handler

1. Increments jiffies.2. Update resource usages (sys + user time.)3. Run dynamic timers.4. Execute scheduler_tick().5. Update wall time.6. Calculate load average.

Slide #45