Portál AbcLinuxu, 5. května 2025 11:20

Jaderné noviny - 12. 12. 2007

4. 1. 2008 | Robert Krátký
Články - Jaderné noviny - 12. 12. 2007  

Aktuální verze jádra: 2.6.24-rc5. Citáty týdne: Ingo Molnár, Ted T'so, Linus Torvalds. Jednodušší syslety. Přiškrcování zápisu nečistých stránek na disk [writeout]. Nové a staré chyby.

Obsah

Aktuální verze jádra: 2.6.24-rc5

link

Aktuální předverze je (k 12. 12. 2007) 2.6.24-rc5, vydaná 10. listopadu. Linus Torvalds k tomu napsal:

Věci se zpomalily, i když bych samozřejmě lhal, kdybych tvrdil, že jsme se postarali o všechny regrese a že je máme pod kontrolou. Ale pracuje se na tom a seznam se krátí. Pokud bych si však měl tipnout, tak před Vánoci 2.6.24 určitě nevyjde - pokud nám Santa nepošle pár elfů, aby s těmi regresemi pomohli.

Seznam oprav je pořád docela dlouhý; byla také doplněna velka aktualizace FireWire stacku. Krátký changelog je součástí Linusova mailu; všechny podrobnosti najdete v dlouhém.

Od vydání -rc5 se do hlavního git repozitáře dostala jen hrstka patchů.

Citáty týdne: Ingo Molnár, Ted T'so, Linus Torvalds

link

Nechci předbíhat, aniž bych si nejprve prohlédl nějaké profily, ale myslím, že ta regrese týkající se výkonu SLUBu dává najevo, že následující je omyl: "SLAB může být implementován mnohem jednodušeji při zachování stejného výkonu".

U SLABu nebylo nic, co bych mohl označit za "nepotřebný kód".

-- Ingo Molnár

Předpokládám, že pokud by NSA měla ve sklepě na plný výkon 20 000 2Ghz procesorů po deset let, tak 50 % času *po té*, co by crackli stav random poolu, by mohli získat posledních 80 bitů generovaných z /dev/random. Ale pokud už uvažujeme o takové síle, která by dokázala získat pool i add_ptr, tak se mi zdá, že by se s tím dalo udělat spousta užitečnějších věcí - třeba vymyslet trojského koně pro ten software a sebrat přímo soukromý klíč.

-- Ted Ts'o

Nic mě nezastaví. Na m0j3 c00l h4ck3rské sch0pn0s1i nikd0 n3má.

-- Linus Torvalds

Jednodušší syslety

link

Syslety jsou navrhovaný mechanismus, který by umožnil, aby bylo kterékoliv systémové volání spuštěno asynchronně; tato technika slibuje ucelenější a jednodušší asynchronní I/O mechanismus a ještě mnohem více - jakmile by se podařilo vyřešit všechny ty nepříjemné drobnosti. Před nedávnem převzal vývoj sysletů Zach Brown a od té doby bylo v té oblasti poměrně ticho. Teď však Zach přišel s novou verzí patche, která ukazuje, kam se tato myšlenka ubírá.

Tato verze odstraňuje většinu funkčnosti, kterou nabízely předchozí verze. Možnost nahrávat do jádra jednoduché programy pro asynchronní spouštění je pryč, stejně jako mechanismus threadletů pro asynchronní spouštění uživatelských funkcí. Místo toho se syslety vrátily ke kořenům: mechanismus pro spuštění jediného systémového volání bez blokování.

Jak už bylo naznačeno v předchozích diskuzích, syslety teď využívají mechanismus systémového volání indirect(). Aplikace, která chce provést asynchronní systémové volání, vyplní strukturu syslet_args, která popisuje, jak má být asynchronní spuštění řešeno; potom aplikace zavolá indirect(), které to provede. Pokud může systémové volání proběhnout bez blokování, indirect() prostě vrátí konečný stav. Je-li zapotřebí blokování, tak se jádro (stejně jako u předchozích verzí patche) vrátí v samostatném procesu do uživatelského prostoru, zatímco původní proces čeká na dokončení. Po dokončení je koncový stav uložen v uživatelské paměti a aplikace je na to zajímavým způsobem upozorněna (vizte dále).

Struktura syslet_args vypadá takto:

    struct syslet_args {
	u64 completion_ring_ptr;
	u64 caller_data;
	struct syslet_frame frame;
    };

Pole completion_ring_pointer obsahuje ukazatel na kruhový buffer uložený v uživatelském prostoru. Hlavička bufferu je definována takto:

    struct syslet_ring {
	u32 kernel_head;
	u32 user_tail;
	u32 elements;
	u32 wait_group;
	struct syslet_completion comp[0];
    };

kernel_head je index další položky v kruhovém bufferu označující dokončení [next completion ring entry], kterou má jádro vyplnit, a user_tail je další položka, která bude předložena aplikaci. Pokud jsou ty dvě položky stejné, je kruh prázdný. Pole elements říká, kolik položek může být v kruhu uloženo; musí jít o mocninu dvou. Jádro používá wait_group jako interní způsob lokalizace čekací fronty, když aplikace čeká na dokončení sysletu; Jonathan Corbet odhaduje, že tato část API do finální verze nepřežije.

A konečně vlastní hodnoty koncových stavů jsou uloženy v poli struktur syslet_completion, které vypadá takto:

    struct syslet_completion {
	u64 stav;
	u64 caller_data;
    };

Po dokončení sysletu je koncový návratový kód uložen do stav, kdežto pole caller_data je nastaveno na hodnotu poskytnutou polem stejného jména ve struktuře syslet_args, když provádění sysletu začalo.

Zbývá jedno pole syslet_args, o kterém se ještě nemluvilo: frame. Definice této struktury se liší na jednotlivých architekturách; pro x86 vypadá takto:

    struct syslet_frame {
	u64 ip;
	u64 sp;
    };

Tyto hodnoty jsou použity, když syslet skončí. Po té, co jádro uloží koncový stav v kruhovém bufferu, zavolá funkci, jejíž adresa je uložena v ip, a to pomocí stackového ukazatele, který je v sp. Toto volání slouží jako jistý druh okamžitého asynchronního upozornění pro aplikaci, že syslet už skončil. Stojí za zmínku, že toto volání je prováděno v rámci původního procesu - toho, ve kterém byl spuštěn syslet - místo v tom novém, který je použit pro návrat do uživatelského prostoru, když se syslet blokne. Tato funkce nemá, co by vracela, a proto by po splnění úkolu měla prostě skončit.

Takže, abychom si zopakovali, jak budou aplikace používat syslety k provádění asynchronních systémových volání:

Pokud by si aplikace přála zastavit a počkat na dokončení všech rozběhnutých sysletů, může využít nové systémové volání:

    int syslet_ring_wait(struct syslet_ring *ring, unsigned long user_idx);

ring je ukazatel na kruh dokončení a user_idx je hodnota indexu user_tail, jak ji vidí proces. Předání user_tail jako parametru do syslet_ring_wait() předchází problémům se souběhem, které by mohly nastat, kdyby syslet skončil poté, co se aplikace rozhodla čekat. Toto volání skončí ve chvíli, kdy je v kruhu alespoň jedno dokončení.

Skutečným účelem této sady patchů je pokus o stanovení uživatelského API sysletů; je zřejmé, že ještě zbývá dost práce. Například v tuto chvíli není možné, aby aplikace použila indirect() k současnému spuštění sysletu a předání dalších parametrů cílovému systémovému volání (což byl původní účel indirect()). Ono je vůbec velmi obtížné rozlišit, která z těch dvou akcí vlastně probíhá. Zach už zmínil, že volací konvenci bude potřeba změnit, aby se jasně vymezilo, kdy se používají syslety a kdy jde o přidávání parametrů.

Navíc je ještě potřeba nalézt odpovědi na několik dalších otázek - Zach jich pár načrtl už při představení patche. Není jasné, jak bude fungovat spolupráce s ptrace(), je dost problémů se správou zdrojů a tak dále. Zach by byl zjevně rád za nějaké podněty ohledně těchto věcí:

Především bych rád slyšel od lidí, kteří se snaží syslety používat ve svých aplikacích. Bude to zatím vyžadovat nechutné berličky místo glibc volání a váš počítač u toho možná vybuchne, ale snad vám bude možnost ovlivnit podobu sysletů za tu námahu stát.

Takže pokud vás zajímá, jak bude toto rozhraní vypadat, mějte teď oči otevřené.

Přiškrcování zápisu nečistých stránek na disk [writeout]

link

Předcházení zatuhávání při zápisu nečistých stránek na disk [writeout deadlocks] je téma, které se čas od času v konferencích objeví. Většina linuxových systémů si s tím umí poradit bez větších problémů. Občas se však systém může dostat do stavu, kdy nemá paměť a musí nějaké stránky zapsat na disk, než je možné další paměť alokovat. Pokud však samotný akt zápisu stránek na disk vyžaduje alokaci paměti, může systém zatuhnout. Nejnáchylnější jsou systémy, které používají komplikované blokové I/O - mapovač zařízení, síťová úložiště, souborové systémy v uživatelském prostoru atd.

Tento problém se už snažilo řešit docela dost patchů; jedním z nich byl i patch pro chytřejší přiškrcování zápisu, o kterém jsme psali v srpnu. Jde však o těžko řešitelný problém; vypadá to, že nás bude doprovázet ještě dlouho. Pokud se ovšem neosvědčí nový a dosti agresivně prosazovaný patch, který poslal Daniel Phillips: přiškrcování zápisu nečistých stránek.

Danielův patch je v jádru docela jednoduchý. Jeho přístup k zamezování zatuhávání spojených se zápisem nečistých stránek je následující:

Patch se nesnaží přímo sledovat množství paměti, které bude použito pro každý požadavek na zapsání stránek; místo toho ukládá ovladačům na blokové úrovni, aby počítaly, kolik bude využito "jednotek". K tomuto účelu přidává do každé fronty požadavků atomic_t proměnnou (nazývanou available) a ukazatel na funkci (metric()). Když se odchozí požadavek dostane do __generic_make_request(), je předán na metric(), aby se získal odhad objemu zdrojů potřebných pro zpracování daného požadavku. Přesahuje-li odhadovaný objem požadovaných zdrojů hodnotu available, proces se blokne, dokud se nedokončí požadavek a available nebude navýšena na dostatečnou úroveň.

Funkci metric() by měl poskytovat blokový ovladač nejvyšší úrovně, který má na starosti frontu požadavků. Pokud je sám ovladač zodpovědný za to, aby se data dostala na fyzické médium, bude odhadování požadovaných zdrojů poměrně jednoduché. Potíže se zatuháváním se však objevují, když musí jít I/O požadavky přes několik vrstev ovladačů; představte si RAID postavený nad síťovými úložnými zařízeními. V takovém případě bude muset horní úroveň získat odhad z nižších úrovní, což je problém, který tento patch zatím neřeší.

Andrew Morton navrhl alternativní přístup, při jehož použití by bylo sledováno využití paměti každého blokového zařízení. Několik háčků [hooks] v kódu pro alokaci stránek by poskytlo rozumný odhad o tom, kolik paměti je v kteroukoliv dobu vyhrazeno pro čekající I/O požadavky; tyto háčky by také mohly být použity k odhadu toho, kolik paměti bude potřebovat každý nový požadavek. Bloková vrstva by pak mohla využít tento odhad a aktuální stav, aby zajistila, že zařízení nepřekročí svůj povolený limit využití paměti. Daniel tento přístup od začátku odmítal, protože by podle něho bylo příliš riskantní sledovat aktuální stav využití paměti. Mohlo by se stát, že by nějaké zařízení obsluhovalo I/O požadavky, které by, ještě než budou dokončeny, vyžadovaly více paměti, než bylo doposud alokováno. V takovém případě by nakonec mohla být skutečná spotřeba paměti o hodně vyšší. Proto Daniel tvrdí, že je lepší provést konzervativní výpočet na začátku.

Patch vůbec neřeší otázku paměťové rezervy; místo toho spoléhá na stávající mechanismus PF_MEMALLOC. Daniel říká, že bylo nezbytné PF_MEMALLOC "upřednostnit" před některými dalšími procesy, které pomáhají s procesem zápisu stránek, ale nic více. Kromě toho také tvrdí, že pro nejlepší výsledky je nutné z jádra odstranit většinu stávajícího kódu cíleného na zabraňování zatuhávání při zápisu stránek. Shrnul to takto:

Rád bych to zakončil tím asi úplně nejpodstatnějším: přiložený kód byl vystaven náročnému testování a používání po mnoho měsíců. Není tedy nic teoretického na tom, když říkám, že funguje - a patch, co se týče korektnosti, mluví sám za sebe. Rád bych k tomu v nepříliš vzdálené budoucnosti dodal, že jsme z jádra odstranili stovky řádků kódu a přitom zachovali stabilitu a zlepšili výkon.

Od té doby se v kódu našlo několik problémů, což trochu narušuje auru korektnosti. Ale nikdo nepoukázal na závažný problém s myšlenkou kódu. Zjišťování skutečné účinnosti a příprava pro to, aby fungoval s větším množstvím úložných konfigurací, však bude vyžadovat čas a další úsilí. Pokud se však zadaří, mohlo by se jádro zbavit jednoho z nepříjemných problémů.

Nové a staré chyby

link

S blížícím se vydáním 2.6.24 roste snaha zbavit se regresí. Jak je vidět na aktuálním seznamu (těsně před vydáním 2.6.24-rc5), pořád ještě zbývá nějaká práce. Seznam je tak dlouhý, že při vydání -rc5 Linus podotkl, že tradiční vánoční vydání tentokrát asi nebude.

Jednou z těchto regresí je to, že s jádry 2.6.24-rc nefunguje určitý model DVD mechanik; s 2.6.23 fungují bez problémů. Pohled na příslušnou stránku v bugzille ukazuje, že na odhalení tohoto bugu bylo vynaloženo docela dost úsilí (jak ze strany vývojářů, tak testerů). V době vydání originálu tohoto článku (12. 12. 2007) ještě nebylo jasné, jak problém opravit.

Ví se však, který patch to způsobil. Tejun Heo to popisuje takto: Je to kvůli nastavení velikosti přenášeného kusu u ATAPI [ATAPI transfer chunk size] na skutečnou velikost, což je obecně správně. Aktuální vývojový kód (určený pro 2.6.25) s tímto zařízením funguje bez potíží, ale to by v této fázi vývojového cyklu byl příliš velký patch pro 2.6.24. Takže Tejun společně s ostatními hledá jednodušší opravu. Má také záložní plán:

Pokud se nám včas nepodaří najít řešení, vždycky tu aktualizaci můžeme stáhnout. Sice kvůli tomu nebudou fungovat některé jiné věci, ale nebude se aspoň jednat o regrese. A opravu pak můžeme začlenit společně s ostatními změnami v 2.6.25.

Tento plán si vysloužil okamžitý nesouhlas Alana Coxe, který připomněl, že kvůli vyřazení této opravy by přestalo fungovat hned několik zařízení, která byla konečně zprovozněna, ale pomohlo by to jen jedinému, o němž se ví, že má s novým kódem problémy. Řekl, že tato změna ...nedává smysl a není obecně ku prospěchu. Alan by raději strpěl, že jedno zařízení nebude fungovat, když to znamená, že by pak větší počet jiných zařízení konečně fungovat začal. Pokud by to bylo potřeba, mohla by být ta nefunkční mechanika dána po dobu 2.6.24 na speciální blacklist.

Proti takovému postupu se však ostře ohradil Linus:

Taková jedna regrese je pravděpodobně jen špička ledovce. Pokud něco přestane fungovat jednomu testerovi, tak to nejspíš znamená, že je dalších tisíc lidí, kteří vůbec vývojové jádro netestovali, nebo s ním měli problém, a tak se prostě vrátili k předchozí verzi.

Naproti tomu vrácení nějaké změny určitě nebude znamenat takové problémy, protože všimnout by si toho mohli jedině ti, kterým to stejně nikdy nefungovalo. Žádný "tichý dav" v takovém případě není.

Spolu s narůstající komplexitou jádra (a obavami o jeho kvalitu) si vývojářská komunita začala dávat na regrese mnohem větší pozor. Jak podotkl Linus, regrese způsobují hmatatelné problémy lidem, jejichž systémy dříve fungovaly; to je dobrá cesta, jak přijít o testery (a nakonec i o uživatele). Na druhou stranu, pokud něco nikdy nefungovalo, a pořád to nefunguje, tak to uživatelům život neztěžuje. Z toho důvodu se potlačování regresí stalo jednou z nejvyšších vývojových priorit.

Existuje ještě jeden příbuzný důvod: zmíněné obavy o kvalitu jádra. Můžeme se ptát, jestli se kvalita jádra zlepšuje, nebo ne, ale opravdová odpověď na tuto otázku se nehledá snadno. Lepší jádro by mohlo přilákat více uživatelů, což by vyústilo ve větší počet hlášení o chybách; stejně tak by mohlo chybovější jádro odradit testery, takže by výsledkem bylo méně hlášených chyb. Nedá se pouze podívat na seznam chyb, o kterých víme, a podle toho posuzovat, jestli je jádro horší nebo lepší než jiné.

Můžeme však dávat pozor na to, aby všechno, co funguje teď, fungovalo i v dalších verzích. Pokud nám věci nepřestávají fungovat, tak za předpokladu, že se čas od času nějaká chyba opraví, můžeme vyvodit, že se jádro zlepšuje. Pokud bychom tolerovali regrese, neměli bychom žádné srovnání. Regrese jsou tedy to nejlepší, co máme (z hlediska objektivního posuzování kvality dané verze jádra). Není tedy divu, že když se kvalitě jádra věnuje více pozornosti, vede to k zaměření na regrese.

Kdokoliv ví něco o práci Alana Coxe, ten také ví, že mu na kvalitě jádra velmi záleží. Tentokrát je však přesvědčen, že tažení proti regresím už zašlo příliš daleko:

Slepě tvrdit, že na regresích tolik záleží, to je někdy (třeba v tomto případě), jako kdybyste tvrdili: "tahle dálnice už není kompatibilní s koňským povozem", takže tu dálnici zase změníme na hliněnou cestu.

Pokud by se pro popisovaný problém nenašlo řešení (pozn.: už se našlo), tak to vypadá, že by asi koně a povozy tentokrát zvítězili. Ti, kdo potřebují pořádnou dálnici, by si museli počkat na verzi kompatibilní s koňmi, která přijde v 2.6.25.

Související články

Jaderné noviny - 5. 12. 2007
Jaderné noviny - 28. 11. 2007
Jaderné noviny - 20. 11. 2007
Jaderné noviny - 14. 11. 2007

Odkazy a zdroje

Kernel coverage at LWN.net: December 12, 2007

Další články z této rubriky

Jaderné noviny – přehled za březen 2025
Jaderné noviny – přehled za únor 2025
Jaderné noviny – přehled za leden 2025
Jaderné noviny – přehled za prosinec 2024
Jaderné noviny – přehled za listopad 2024

Diskuse k tomuto článku

4.1.2008 00:22 Jirka P
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Odpovědět | Sbalit | Link | Blokovat | Admin
ta regrese týkající se výkonu SLUBu naznačuje následující problém: "SLAB může být implementován mnohem jednodušeji při zachování stejného výkonu".
Tohle je dost nešťastně přeloženo, až to nedává smysl. Místo "problém" (fallacy) by mohlo být "omyl", "pomýlenost", nebo "pověra".
5.1.2008 02:51 Jiří J. | skóre: 34 | blog: Poutník | Brno
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Navíc pokud je "týkající se výkonu SLUBu" vsuvka, měla by být oddělena (čárky/pomlky/...).
5.1.2008 03:45 Jiří J. | skóre: 34 | blog: Poutník | Brno
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Ještě bych rád podotknul pár věcí, kterých jsem si teď - v polospánku - všiml:
Místo toho se syslety vrátily ke kořenům: mechanismus pro spuštění jediného systémového volání bez blokování.
Existuje ještě jeden příbuzný důvod: zmíněné obavy o kvalitu jádra.
Zaměnil bych dvojtečky za středníky, přeci jen je dvojtečka znak "natvrdo" ukončující větu.

Přesahuje-li odhadovaný objem požadovaných zdrojů hodnotu available, proces se blokne, dokud se nedokončí požadavek a available nebude navýšena na dostatečnou úroveň.
Není náhodou "dokud se nedokončí požadavek" věta vedlejší (oddělená z obou stran čárkami), následována 3. větou hlavní (a available nebude navýšena na dostatečnou úroveň), která je ve slučovacím poměru vůči druhé hlavní?

Můžeme se ptát, jestli se kvalita jádra zlepšuje, nebo ne, ale opravdová odpověď na tuto otázku se nehledá snadno.
Zde bych před "nebo" čárku nedával, přiznávám, že ne všechno si ze základní školy pamatuji, však domnívám se, že před "nebo" se čárka nepíše, pokud se jí neodděluje věta vedlejší, ...

Uznávám, je to kosmetika, pokud mám alespoň v něčem pravdu, snad to pomůže v korekci.
5.1.2008 14:54 trekker.dk | skóre: 72
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Zaměnil bych dvojtečky za středníky, přeci jen je dvojtečka znak "natvrdo" ukončující větu.
Podle mě jsou ty dvojtečky použity naprosto správně.
Quando omni flunkus moritati
7.1.2008 12:38 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Ano. Případně lze použít pomlčku.

Středník je silnější čárka – odděluje seznamy v seznamu, připadně vyjadřuje užší připojení jiné myšlenky, kde tečka by byla příliš důrazná.
7.1.2008 12:43 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Před nebo se čárka píše, jde-li o poměr vylučovací v souřadném spojení (vzpoměňme vtip o informatikovi nakupujícím jablka [,]nebo hrušky).
6.1.2008 18:18 Kyosuke | skóre: 28 | blog: nalady_v_modre
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Proč "pověra"? Tuhle konotaci tam moc nevidím. Proč ne prostě "chybná úvaha" nebo něco na ten způsob? :-)
6.1.2008 20:07 Sinuhet | skóre: 31
Rozbalit Rozbalit vše Re: Jaderné noviny - 12. 12. 2007
Odpovědět | Sbalit | Link | Blokovat | Admin
Prijde mi zvlastni deklarovat ukazatele jako u64.

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.