Portál AbcLinuxu, 5. května 2025 23:50
Aktuální verze jádra: 2.6.19-rc5. OSDL bude platit autora dokumentace. Sledovače úloh. Současná verze rozhraní kevent. Sparse získal nového správce.
Aktuální předverze řady 2.6 je 2.6.19-rc5, vydaná 7. listopadu. Obsahuje zase hromadu oprav, z nichž mnohé se týkají jednotlivých architektur; podrobnosti v dlouhém changelogu. Linus o tom řekl: možná bude i -rc6, ale třeba ji ani potřebovat nebudeme.
Adrian Bunk stále spravuje seznam regresí v 2.6.19-rc5.
Aktuální verze -mm stromu je 2.6.19-rc5-mm1. Mezi nedávné změny patří čerstvý kevent kód (vizte níže), sada patchů jaderného virtuálního stroje a velké aktualizace časovače s vysokou přesností a dynamického tiku - který má i nadále nějaké problémy.
Aktuální stabilní verze řady 2.6 je 2.6.18.2, vydaná 3. listopadu. Také obsahuje slušnou řádku patchů.
3. listopadu vyšla verze 2.6.16.30 a 7. listopadu následovala 2.6.16.31. Mezi těmito dvěma verzemi bylo opraveno docela dost chyb, včetně několika bezpečnostních problémů.
Pro uživatele 2.4 byla 4. listopadu vydána verze 2.4.34-pre5. Zanedlouho by měla vyjít také první RC verze 2.4.34.
Trvalo to dlouho, ale nakonec k tomu došlo: OSDL shromáždila dostatek prostředků na financování technického autora, který bude po dobu jednoho roku pracovat na dokumentaci k jádru. Pozice je nabízena na netu všem, kdo by měli zájem.
Jednou z komplikovanějších jaderných funkcí je copy_process() v kernel/fork.c. Tato rutina je srdcem systémových volání fork() a clone(); musí vytvořit koherentní kopii běžícího procesu, přičemž je třeba dbát na všechny přítomné klonovací příznaky. Je tam šestnáct různých goto značek pro chybová ukončení. Tedy zjevně místo, kde se může hodně věcí pokazit.
Ta operace se týká také mnoha dalších jaderných subsystémů. Mnohé z těchto subsystémů by rovněž chtěly vědět o dalších událostech během životního cyklu procesu, což má za následek, že jsou v celém kódu procesu umístěny háčky. Pro získávání informací o událostech týkajících se procesu by bylo fajn mít k dispozici úhlednější řešení.
A to úhlednější řešení se zdá být na dosah v sadě patchů od Matta Helsleyho: sledovače úloh [task watchers], teď ve druhé verzi. Tento patch věc řeší pomocí zajímavého přístupu: poskytuje v podstatě pouze další oznamovací rozhraní, aby se minimalizovala režie v částí jádra, kde velmi záleží na výkonu.
"Sledovač úlohy" je v tomto případě funkce, která je upozorněna vždy, když se ve spojení s procesem stane nějaká zajímavá událost. Sledovače mají následující prototyp:
int my_watcher(unsigned long info, struct task_struct *tsk);
Když je sledovací funkce zavolána, bude mít info o události další informace, kdežto tsk ukáže na proces, který událost generuje. Zavolání sledovače událostí se dá zařídit prostým přidáním deklarace podobné této:
task_watcher_func(event, function);
Kde event je událost, která nás zajímá, a function je sledovací funkce, která má být v reakci na danou událost zavolána. Možné události jsou:
Makro task_watcher_func() vytváří ukazatel na sledovací funkci ve speciální sekci ELF. Pro každou sledovanou událost je samostatná sekce; když je taková událost signalizována, sledovací kód prostě projde každou funkcí v příslušné sekci. Z takového mechanismu vyplývají dvě věci: sledovače událostí existují po dobu života systému (nelze je zaregistrovat a odregistrovat) a nemohou být umístěny v natahovatelných modulech (ačkoliv toto omezení bude později odstraněno).
Dalo by se uvažovat o tom, proč je to řešeno takto, a ne pomocí jednoduchého seznamu oznamovačů. Jonathanu Corbetovi to bylo divné, a proto se na to zeptal pana Helsleye. Potíž je v tom, že vytváření procesů je část jádra, která je velmi náročná na výkon. A každá změna, která zvyšuje dobu větvení procesu, bývá pečlivě zkoumána. Tato doba je měřena různými testy; rychlé vytváření procesů je u zátěží náročných na větvení procesů také důležité. A protože kompilace jádra může vyžadovat hodně větvení, existuje opravdu velká motivace k tomu, aby to zůstalo co nejrychlejší.
Je-li seznam oznamovačů použit společně se sledovači, je potřeba nějaké zamykání, aby nebyl seznam při přidávání a odebírání sledovačů poškozen. Ty samostatné ELF sekce jsou pak vytvořeny už při kompilaci jádra jako struktury "pouze pro čtení". Znamenají tedy pro proces menší režii a jsou tím pádem méně trnem v oku vývojářům, kterým na funkcí sledovačů třeba tolik nezáleží.
Navrhované rozhraní kevent bylo naposledy probíráno v srpnu. Toto nové API, které chce aplikacím poskytnout jediné rozhraní pro přijaté události, je vyvíjeno už skoro rok. A vyvíjí se dál, takže na oslavu vydání verze 23 kevent patche se na něj opět podíváme.
Některé části rozhraní jsou relativně stabilní. Hlavní multiplexovací systémové volání tedy zůstává:
int kevent_ctl(int fd, unsigned int cmd, unsigned int num, struct ukevent *arg);
Funkcí prováděných tímto voláním je však méně. Především už není využíváno k vytváření popisovače souboru kevent; místo toho je otevřeno /dev/kevent. Ale kevent_ctl() je i nadále místo, kam se přidávají události, které nás zajímají. Tam se také upravují a odtud odebírají.
Synchronní rozhraní pro čekání na události je také pořád skoro stejné:
int kevent_get_events(int fd, unsigned int min_nr, unsigned int max_nr, __u64 timeout, struct ukevent *buf, unsigned flags);
Toto systémové volání počká, dokud není ke zpracování připraveno alespoň min_nr událostí, a pak zkopíruje max_nr dokončených událostí do buf. Volání je však ukončeno předčasně, pokud uplyne timeout nanosekund předtím, než je signalizováno min_nr událostí. Aktuální dokumentace kevent říká, že nekonečného čekání lze dosáhnout předáním hodnoty -1 do timeout - trošku zvláštní, vezme-li se v úvahu, že timeout je neznaménková veličina. Nebylo by překvapením, kdyby byla pro tento účel definována například nějaká hodnota KEVENT_WAIT_FOREVER.
Největší změny proběhly v kódu kruhového bufferu kevent, který šlo posledně použít jen dosti krkolomně. Předchozí implementace také buffer umísťovala do pevně určené jaderné paměti, což mohlo systém potenciálně vystavit DoS problémům. V nové implementaci je tedy kruhový buffer zcela v uživatelském prostoru. Aplikace prostě alokuje pole požadované velikosti s následujícím typem:
struct kevent_ring { unsigned int ring_kidx; struct ukevent event[0]; };
Skutečný počet událostí, které mají být v kruhu uloženy, určuje aplikace. Subsystému kevent je nutno o tomto kruhu říci pomocí
int kevent_ring_init(int fd, struct kevent_ring *ring, unsigned int num);
kde num je počet ukevent struktur v kruhu. Volání si bude pamatovat velikost a adresu kruhu a nastaví ring_kidx - index záznamu, kam bude jádro ukládat další dokončenou událost - na nula.
Při práci s kevent kruhem je třeba mít několik věcí na paměti. Jednou z nich je, že v této datové struktuře není místo na sledování toho, kterou událost má aplikace zpracovat jako další; aplikace si takový index musí uložit jinde. Také to vypadá, že neexistuje způsob, jak kruhový buffer odpojit nebo změnit jeho velikost, aniž by se prostě zavřel popisovač souboru události a začalo se znovu; pokus o nahrazení jednoho kruhu jiným selže. A nakonec: aplikace musí jádru říci, aby události do kruhu dával:
int kevent_wait(int fd, unsigned int num, __u64 timeout);
Toto systémové volání počká, dokud nebude k dispozici alespoň jedna událost, a potom do kruhového bufferu zkopíruje až num událostí. Jakmile jsou události zkopírovány, jádro předpokládá, že byly zpracovány, a zapomene na ně (nebo je znovu zařadí do fronty, pokud to událost vyžaduje). Aplikace se událostmi může probírat podle svého - třeba zastavovat předtím, než narazí na aktuální hodnotu ring_kidx - není již potřeba žádných volání.
Současné API se asi nejvíce zalíbilo lidem, kteří mají rádi o všem přehled - i když chvíli trvalo, než se ozval důležitý hráč Ulrich Drepper. V minulosti se mu nelíbil parametr časového limitu (protože by raději, aby rozhraní používalo absolutní a ne relativní hodnotu timespec). Ulrich také navrhl, že by blokovací systémová volání mohla používat verzi, která specifikuje masku událostí, podobně jako nedávno začleněná systémová volání ppoll() a pselect(). Poukazuje na to, že ačkoliv je možné přijímat signály jako kevent, některé aplikace budou určitě používat tradiční signály s tradičními problémy atomičnosti.
Takže než bude kevent API začleněno do jádra - a tím vytesáno do kamene - bude možná potřeba vyřešit několik zbývajících problémů. Ale věci se zjevně hýbají správným směrem a počet vývojářů, kteří o toto API projevují zájem, se zvyšuje. Nemuselo by to trvat dlouho a Linux bude mít vlastní jednotné rozhraní pro události.
Utilita "sparse" byla dlouho jedním z nejlépe střežených tajemství Linuxu. Jde o nástroj pro statickou analýzu, který dokáže ve zdrojácích jádra nalézt mnoho druhů chyb. Sparse je užitečný, ale překvapivě těžko k mání. Nikdy neměl vlastní webovou stránku a skoro žádné distribuce ho nenabízejí jako balíček. Mají-li uživatelé zájem, musí buď vystopovat git strom nebo zabalené zdrojáky od Davea Jonese.
Původním autorem sparse je Linus Torvalds, který se mu však již nějakou dobu nevěnuje. Nedávno navrhl, aby to převzal někdo jiný:
Řekl bych, že by bylo lepší, kdyby mě lidi nepovažovali za správce sparse, protože už to prostě umí věci, které jsem potřeboval, a tudíž to nechávám ležet.
Výsledkem této diskuze je, že sparse má správce nového: Josh Triplett. Josh odstartoval verzí sparse 0.1, vůbec prvním vydáním sparse, které má číselné označení verze. Založil pro sparse nový git strom a dokonce i webovou stránku.
Mám v plánu vydávat nové verze sparse pravidelně a také dosáhnout zařazení do distribucí - alespoň do "experimentálních" větví. Případné zájemce z řad správců balíčků prosím, aby se přihlásili do konference linux-sparse, a dali mi vědět, jak mohu pomoci, aby šlo všechno hladce.
Původním autorem sparse je Linus Torvald, ...Torvalds...
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.