IRQ handling

Transkript

IRQ handling
SWI 075 – Linux Kernel
IRQ handling
Outline
●
●
●
●
●
ISR – top half versus. bottom half
IRQ kernel API (registrace a odregistrování
ISR, ...)
Implementace; shared handlery; real-life
příklad (TSC)
Zakázání/povolování interruptů
Bottom halves
–
–
–
–
Základní principy
Softirqs
Tasklets
workqueues
Interrupt basics
●
●
●
●
Jeden z hlavních úkolů kernelu – komunikace
se zařízeními
CPU posle request a čeká na odpověď od
zařízení. CPU daleko rychlejsí nez HW ->
nevýhodné
Polling – kernel se periodicky dotazuje HW,
jestli obslouzilo request. Overhead
Interrupt – device dá samo kernelu
asynchronně vědět.
Interrupt basics
●
●
●
Interrupty – elektrické signály od zařízení pro
CPU
CPU přijme interrupt a vyvolá v OS příslusný
obsluzný kód, který data od device zpracuje
HW generuje přerusení vzhledem k CPU
asynchronně -> kernel můze být “kdykoliv”
přerusen aby zpracoval interrupt
IRQ
●
●
●
OS potřebuje vědět které HW vyvolalo
interrupt (pro zavolání odpovídající ISR)
IRQ lines - “jednoznačná” identifikace
zařízení (např. IRQ 0 – timer, IRQ 1 –
keyboard (na PC))
Ne vzdy přesně předem definováno (např.
IRQ na PCI přidělovány dynamicky)
Sidenote - IRQ a exceptions
●
●
●
Exceptions na rozdíl od interruptů vznikají
vzhledem k CPU taktu synchronně (CPU si
je generuje sám)
Dělení nulou, pagefault, instrukce int...
Větsina CPU obsluhuje exceptions velmi
podobně jako interrupty -> kernel má pro
oboje velmi podobnou infrastrukturu
ISR
●
●
●
ISR – Interrupt service routine (aka interrupt
handler)
Kazdé zařízení generující interrupty má svůj
interrupt handler – součást ovladače daného
HW
V linuxu standardní C funkce s pre-defined
prototypem (předávání parametrů od
generického interrupt handling kódu)
ISR
●
●
●
ISR musí být spustěna co nejdřív – HW
nemůze interrupt “drzet” dlouho
Interrupt nastává asynchronně -> ISR můze
být spustěna kdykoliv -> nesmí trvat dlouho
ISR musí (např síťová karta): potvrdit příjem
interruptu řadiči, zkopírovat data z HW do
paměti, zpracovat, předat příslusnému
stacku nebo aplikaci ...
ISR – top vs bottom half
●
●
●
●
Kontrast: ISR musí bězet rychle vs musí
dělat dost práce
Rozdělení zpracovávání interruptů na dvě
části –
top half (ISR, time critical, bězí hned) a
bottom half (bězí později, dělá náročnějsí
práci)
ISR – request_irq()
●
●
●
●
●
int request_irq(unsigned int irq,
irqreturn_t (*handler) (int, void *,
struct pt_regs *), unsigned long
irqflags, const char *devname, void
*dev_id);
irq – číslo IRQ které bude handler obsluhovat; starsí
PC devices (keyb, timer, ...) hardcoded. PCI – probing
handler – pointer na ISR – tato funkce zavolána při
kazdém interruptu
devname – ASCII jméno – viz /proc/irq a
/proc/interrupts
dev_id – kvůli shared IRQs (NULL pro non-shared).
Unikátní pro zařízení (obyčejně příslusné struct device
– můze se v handleru hodit)
ISR – request_irq()
●
●
irqflags – zbitmaskování následujících:
– 0
– SA_INTERRUPT (fast – historický relikt. Dnes fast
interrupty pouze zakazují vsechna přerusení, nejen
sebe sama). Pouzívá dnes vpodstatě jen timer
– SA_SAMPLE_RANDOM – IRQ pouzitelné jako zdroj
entropie (nehodí se např pro timer, ale ani síťovku)
– SA_SHIRQ – tato IRQ line můze být sdílena více
handlery. Kazdý handler na dané line musí toto
specifikovat.
pt_regs – obsah registrů CPU v době přerušení.
Hlavně pro debugování
ISR – request_irq()
●
●
●
Překvapení(?) – request_irq() nesmí být voláno z
míst která nesmějí usnout (interrupt context, zamknutý
spinlock)
Obskurní důvod – operace se záznamy v /proc volá
kmalloc()
Pozn: je důlezité inicializovat zařízení a ovladač před
voláním request_irq()
ISR
●
●
●
Návratové hodnoty:
– IRQ_HANDLED - “ano, to je moje”
– IRQ_NONE - “k tomu se neznám, zkus
dalsí handler”
Z návratových hodnot kernel IRQ subsystem
můze detekovat HW který vysílá spurious
interrupty
Umozňují sdílení – kernel zkousí vsechny
handlery pro dané IRQ, dokud nedostane
IRQ_HANDLED
ISR - nesting
●
●
Linuxový kernel nevyzaduje aby byly ISR
reentrantní
Daná IRQ line je vzdy maskována na vsech
procesorech – ISR můze být přerusena ISR
od jiného IRQ, ale nikoliv od stejného
Interrupt context
●
●
Process context
– Vlákno v kernel mode (kernel thread nebo
syscall/exception procesu)
– Můze blokovat a později být znovu
schedulováno
Interrupt context
– Kernel !vseho nechá” a obsluhuje interrupt
– Není svázáno s zádným procesem
– Nemůze blokovat (nebylo by mozné ho
reschedulovat)
– Time critical – přerusen jiný kód (potencionálně
jiný ISR)
– Sdílený per-CPU 4K stack pro vsechny ISR
Interrupt handling
●
Arch-specific (CPU, interrupt controller)
Enable/Disable IRQ
●
●
●
●
local_irq_disable() / local_irq_enable()
Problém s vnořováním (můzeme být volání s
povolenými i zakázanými interrupty) ->
local_irq_save(flags) /
local_irq_restore(flags)
unsigned long flags – arch-specific
data o
interrupt systému
SPARC do flags ukládá i informace o stack
frame – není mozné flags předávat mezi
funkcemi!
Enable/Disable IRQ
●
cli() / sti() - (podle x86 názvosloví)
–
–
●
●
mrtvé od 2.5 (scalability)
Obsluha prerusení musí pouzívat jen lokální
zakazování přerusení a spinlocky
disable_irq(unsigned int irq) /
disable_irq_nosync(unsigned int irq)
– Zakáze radiči přerusení doručovat dané IRQ vsem
procesorům v systému
– _nosync() neblokuje dokud vsechny handlery
nedoběhnou
– Legacy interface – není slusné zakazovat IRQ při
sdílení IRQ mezi více zařízeními
in_interrupt() (ISR||BH) , in_irq()(ISR)
Bottom halves - softirq
●
●
●
●
kernel/softirq.c
Nepříilis často pouzívané (spíse tasklety)
Alokovány v compile-time staticky (narozdíl
od taskletů), maximálně 32 (v současnosti 6)
– timer, síť (2x), SCSI, implementace
taskletů (2x)
Je-li pending softirq se testuje při
– Návratu z interrupt handleru
– V kernel threadu ksoftirqd
– Explicitně (to dělá jen network subsys)
Bottom halves - softirq
●
●
●
●
raise_softirq() označí softirq jako
pending; je spustěno při dalsí přílezitosti kdy
kernel zpracovává softirqs
Bězí se zakázanými interrupty, v interrupt
contextu
Při běhu jsou softirqs na lokálním procesoru
zakázána (na SMP můze to samé softirq
vykonávat jiné CPU -> potreba zamykání)
Bottom halves - softirq
●
Přidání:
– MY_SOFTIRQ do enumu v
linux/interrupt.h
– open_softirq(MY_SOFTIRQ,
my_handler, NULL /* data */);
– raise_softirq() /
raise_softirq_irqoff()
● (jen malá optimalizace – raise_softirq()
vypiná interrupty, _irqoff() dává hint
ze uz jsou vypnuté)
Bottom halves - ksoftirqd
●
●
●
●
●
●
Softirq mohou být aktivovány hodně často, navíc se
mohou samy reaktivovat
Okamzité zpracovávání reaktivovaných softirqs ->
userspace starvation
Na druhou stranu není mozné reaktivovaná softirqs
odkládat
Řesení – reaktivovaná softirqs se nespoustějí ihned
Pod velkým loadem se vzbudí ksoftirqd thread (nice
19 – nic důlezitého není odlozeno)
Nedojde k user-space starvation, a zároveň to
“excessive” softirqs pustí rozumně brzy
Bottom halves - tasklety
●
●
●
●
●
●
Dynamicky definované v runtime, implementace
pomocí speciálního statického softirq
Mají jednodussí interface než softirqs a jednodussi
zamykání sdílených struktur
Větsině implementací stačí tasklety – softirqs jen
pro velmi high-frequency/threaded situace
Stejně jako softirqs bězí v interrupt contextu
Je zaručeno ze daný tasklet bězí vzdy jen jeden
(narozdíl od softirqs na SMP)
HI_SOFTIRQ a TASKLET_SOFTIRQ – dvě priority –
HI_SOFTIRQ bězí vzdy pred TASKLET_SOFTIRQ
Bottom halves – tasklety - API
●
●
●
●
DECLARE_TASKLET(my_tasklet,
my_handler, data);
– Makro deklarující staticky struct
tasklet_struct
struct tasklet_struct my_tasklet;
tasklet_init(my_tasklet, my_handler,
data);
– Dynamická definice taskletu
Rozhodnutí mezi statickou a dynamickou definicí –
zálezí jestli je třeba mít pointer na tasklet
tasklet_schedule() (obdoba
raise_softirq() - to se také “v pozadí” zavolá),
tasklet_kill(), ...
Bottom halves – workqueues
●
●
●
●
Odsunutí práce do kernel threadu
Výhoda – bězí v proces kontextu – má
dovoleno spát
Zpracovává kernel thread events/n (n –
číslo CPU)
Opět podobné API jako pro tasklety/softirqs,
viz linux/workqueue.h
Summary
●
Top half interrupt handlery
–
–
–
–
●
Mohou sdílet jedno IRQ
Bezí s blokovaným přerusením
Jen nejnutnějsí úkony
Interrupt context
Bottom half interrupt handlery
–
–
–
softirqs – definované staticky, mohou bězet
soubězně
Tasklety – lze definovat dynamicky, nemohou
bězet dva stejné najednou
Work queues – jediné v proces kontextu, mohou
spát

Podobné dokumenty

zde - Liturgie.cz

zde - Liturgie.cz o novou evangelizaci, trvá tento důlezitý aspekt v církvi dnešní, která chce bez jakéhokoliv rozdílu přijímat muze i zeny patřící ke kterékoliv rase, kterémukoliv lidu, jazyku i národu (srov. Zj 5,...

Více

Depeche Mode Friends

Depeche Mode Friends V rozhovoru se zpěvačkou kapely Prapaganda Claudií Brücken v časopise Destination Pop padlo také jméno Martina L. Goreho. "Známe se s Martinem už pár let. V hlavě jsem nosila pár písní, které byly ...

Více

sborník

sborník liberalizovaný trh s elektřinou. Takto provedené dělení je zavedeno z důvodu rozlišení a určení důležitosti jednotlivých institucí. Pro rozdělení institucí je hlavním faktorem jejich vztah k trhu. ...

Více