Asynchronní systémová volání, syslety a threadlety
Celý únor byl pro jaderné vývojáře ve znamení asynchronních I/O operací (AIO) a systémových volání. Podpora AIO nebyla v Linuxu nikdy úplná (snad kromě přímých operací souborových systémů) a i když existují nějaká řešení, nejsou zrovna jednoduchá a asynchronní zacházení je nutné řešit explicitně v každém subsystému. Koncem ledna se problém snažil řešit Zach Brown pomocí tzv. fibril ("nitek") - vlákének jádra umožňujících asynchronní volání nejen I/O operací, ale libovolných systémových volání. Podrobný rozbor viz lwn.net/Articles/219954/.
Fibrily se sice nevykonávaly paralelně vedle sebe, řadily se do fronty a vždy běžela jen jedna, ale práce s nimi měla být rychlejší než s jadernými vlákny nebo procesy. Když proces zavolal asynchronní systémové volání, jádro vytvořilo novou fibrilu a v ní toto volání vykonalo. Pokud by fibrila s voláním blokovala, byla by zařazena do fronty a řízení se vrátilo volajícímu uživatelskému procesu, který by si výsledek vyzvedl později. Výhodou Zachova řešení je, že téměř vůbec nevyžaduje změny v samotných systémových voláních a ostatním kódu jádra. Mělo ale být spíše jen ukázkou než hotovým řešením. Linusovi se líbilo, ale Ingo Molnarovi už ne, podle něj je přepínání procesů nebo jaderných vláken dostatečně rychlé a fibrily nestojí za komplikování plánovače.
Z následné diskuze vzešly v polovině února vlastní návrhy řešení asynchronních systémových volání (lwn.net/Articles/221913/) jak Linuse, jednoduché, pomocí procesů, vytvářející při blokování nový proces, tak Inga, nazvané syslety ("syscall plugins") a používající při blokování nová paralelní jaderná vlákna (zvané atomy). Vyvíjející se kód sysletů se ukázal být rychlejším než stávající asynchronní I/O implementace, která je navíc na hranici svých možností. Během vývoje vznikly jako nový zásadní prvek také threadlety (lwn.net/Articles/223899/), poskytující funkcionalitu sysletů v userspace pomocí (uživatelských) vláken a zjednodušující práci s asynchronně vykonávaným kódem. Ingo to nazývá "paralelizmem na požádání" - program se nemusí starat o vytváření vláken, při blokování je vytvoří jádro samo.
Koncem února ale vyvstala překvapivě opomíjená otázka: a co kevent? Kevent (lwn.net/Articles/213672/) je kód, který se snaží jeho autor Evgeniy Polyakov dostat do hlavního stromu jádra téměř rok a který poskytuje také asynchronní I/O operace a řeší tak stejný problém, kvůli kterému vznikly fibrily, syslety a nakonec threadlety. Jednodušší kevent na rozdíl od threadletů řeší (jen) asynchronní události a je na to optimalizovaný, ale právě I/O operace jsou řešeny událostmi a např. na síťování, kde se často blokuje, se threadlety vůbec nehodí. Ingo oponoval tím, že threadlety jsou obecnější a řeší i případy, kdy obsluha události blokuje, a jsou také jednodušší pro použití ve vícevláknových programech i v jádře (příkladem náročnějšího použití kevent mohou být bufferované souborové AIO).
Do diskuze se nakonec vložil Linus s tím, že v jádře může být obojí. Událostmi řízené asynchronní vykonávání na události i vláknově řízené na obecný kód, který může blokovat. Jak je vidět, řešení asynchronního vykonávání kódu nejen systémových volání, ale i souborových systémů a ovladačů zařízení není vůbec jednoduché. Nicméně, v budoucnu s ním lze v jádře a zprostředkovaně i v glibc/libaio určitě počítat.
Vysoce přesné časovače a "beztikové" jádro
Jednou z významných novinek příští verze jádra 2.6.21 bude obecné rozhraní časovačů, tzv. clockevents, a dynamické časování jádra, tzv. dyntick/nohz, Ingo Molnara a Thomase Gleixnera (lwn.net/Articles/223185/). Tento kód měl být už ve verzi 2.6.19, ale nesplňoval jedno ze základních pravidel vývoje jádra: "Jestliže váš kód znefunkční laptop Andrew Mortona, těžko se dostane do hlavního stromu jádra" :-).
Pro plánování časovačů doposud neexistoval v jádře obecný kód, zacházelo se nimi na architektuře závislým, místy zbytečně duplikovaným, kódem. Obecné rozhraní pro udržování času (generic time of day) bylo zařazeno již dříve, ale pro programování libovolných časovačů teprve nyní. Tento kód, clockevents, navíc přináší i vysoce přesné časování (co hardware dovolí, typicky 1 mikrosekundu) oproti přesnosti časování jádra (tzv. HZ value). Tato vlastnost je vyžadována mj. uživateli real-time aplikací a bude ji možné zapnout konfigurační volbou CONFIG_HIGH_RES_TIMERS.
Tímto kódem je nově řešeno i časování samotného jádra a tato část, dyntick, odstraňuje zbytečné tiky, pokud systém zrovna nemá nic užitečného na práci (idle time). To znamená, že procesor nebude zbytečně přerušován pravidelně, periodicky podle hodnoty HZ value, např. 250krát za sekundu, ale jen podle potřeby (třeba i jen 1 až 2krát za sekundu), což by mohlo přinést úsporu energie a menší teplotu procesoru. Toto "beztikové" jádro půjde zapnout konfigurační volbou CONFIG_NO_HZ. Nicméně toto ještě není zcela "beztikové" řešení, zatím pouze v idle režimu, úplné zrušení periodického časování jádra je v plánu a jistě to nebude dlouho trvat, co bude v jádře také. To bude ještě více než dosavadní řešení znát hlavně u virtualizovaných systémů, kde by se mělo projevit dalším zrychlením.
Jan Outrata
www.kernel.org