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
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,...
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 ...