Portál AbcLinuxu, 5. května 2024 13:22

Jaderné noviny - 9. 5. 2007

31. 5. 2007 | Robert Krátký
Články - Jaderné noviny - 9. 5. 2007  

Aktuální verze jádra: 2.6.21. Citáty týdne: Ingo Molnar, Jeff Garzik, Linus Torvalds. Další věci pro 2.6.22. Návrat kevent? Potíže s volatile.

Obsah

Aktuální verze jádra: 2.6.21

link

Stále nevyšla žádná předverze řady 2.6 (k 9. 5. 2007), protože ještě probíhá začleňování změn. Do hlavního git repozitáře se valí další patche; vizte níže.

Aktuální verze -mm stromu je 2.6.21-mm2. Mezi nedávné změny patří odstranění patchů s adaptivním přednačítáním [adaptive readahead] (čeká se na novou, jednodušší verzi), jaderného mechanismu pro mountování neprivilegovanými uživateli a nakonec odstranění schodišťového plánovače s příděly [staircase deadline scheduler]. -mm však hubne především kvůli přesunu patchů do hlavního stromu.

Starší jádra: 2.6.16.50 bylo vydáno 4. května a 2.6.16.51 následovalo 9. května. Obě obsahují několik důležitých oprav.

Citáty týdne: Ingo Molnar, Jeff Garzik, Linus Torvalds

link

Vážně, bylo by asi lepší, kdybychom riskli začlenění _špatného_ kódu teď (což je v případě přednatahování swapu [swap prefetch] přesný opak skutečnosti), než nechat ten kód ležet ladem. Lidem zjevně vadí některé aspekty swapování na desktopu a jediným způsobem, jak z toho ven, je nechat na tom kódu hackovat více lidí. Začlenění kódu zapojí více lidí. Bude to kravál a mohlo by dojít k regresím, ale aspoň jde v tomto případě jen o "výkonnost" a tu funkci jde snadno vypnout.

-- Ingo Molnar prosazuje swap prefetch.

Motto open source je vydávej brzy, vydávej často. Ne "schovej ten kód někde v temném koutě, dokud si Christoph nemyslí, že je dokonalý". Pro upstream začleněný kód máme vysoké očekávání, ale neočekáváme dokonalost. Dokonalý je nepřítelem dobrého.

-- Jeff Garzik pro Libertas.

Pokud vaše mise k jiné hvězdě *závisí* na tom, aby každý kousek komplexního vybavení vydržel více než 200 let bez rebootu, tak máte vážné technologické problémy.

-- Linus Torvalds

Další věci pro 2.6.22

link

V tuto chvíli probíhá začleňování změn pro 2.6.22 a hodně kódu se ještě očekává. Již zařazené změny, kterých si všimnou i uživatelé, jsou následující:

Změny patrné pro vývojáře jádra:

Proces začleňování ještě neskončil, takže se můžete těšit na další velkou dávku patchů.

link

Když jsme naposledy rozebírali rozhraní kevent od Jevgenije Poljakova, vypadalo to, že už je u konce svého života. Patche eventfd byly najednou na výsluní, protože aplikacím nabízely způsob, jak čekat na mnoho druhů událostí při použití obyčejných dotazovacích [polling] rozhraní. Vývojář kevent dal práci do šuplíku, neboť nepředpokládal, že by se mohla do jádra dostat. Takový předpoklad se zdá být oprávněný - vzhledem k tomu, že Andrew Morton ve svém dokumentu o plánovaném začleňování do 2.6.22 říká, že budou zařazeny patche eventfd.

Jak bylo řečeno minulý týden, jedna překážka se našla - pollfs, což je implementace velmi podobné myšlenky. Objevila se ale i relativně tvrdá kritika kódu pollfs a vypadá to, že jeho prestiž dost poklesla. Je možné, že brzy vyjde nová, vylepšená verze pollfs, ale to by musela být o hodně lepší, aby upoutala dostatek pozornosti. Kód pollfs má smůlu také v tom, že na scénu přišel příliš pozdě.

Je tu však další pozdní příchozí, kterému ale pozornost věnována bude: správce glibc Ulrich Drepper. Přestože se neúčastnil diskuze o eventfd, teď vystoupil proti začlenění do hlavního stromu:

Záleží na Linusovi, jestli chce přidat další kód, další možné problémy, další noční můru pro správce - jen kvůli dočasnému řešení, které není nutné, které neřeší všechny problémy, a které není tak škálovatelné jako další navrhované metody.

Můžu říct jen to, že bych byl proti. Prostě to nedává smysl.

Ulrichovi se na přístupu eventfd nelíbí několik věcí:

Výsledkem je, že Ulrich oponuje začlenění eventfd; byl by raději, kdyby se věnovalo úsilí přípravě kevent (nebo nějaké náhradě s podobnými funkcemi). Rozhraní podobné kevent prý nakonec stejně bude nutné:

Myslím, že nakonec stejně budeme potřebovat něco jako kevent, a pak bude všechno tohle *fd() zbytečné a bude to jen kód navíc, který bude nutné udržovat, a který by mohl ztěžovat další práci v této oblasti.

Jak to dopadne, to vůbec není jasné. Ulrichův názor žádné velké houfy vývojářů nepodpořily - ale nikdo mu také neodporuje. Zatím ani ještě nikdo neoprášil patche kevent pro další kolo diskuzí. Jedna věc se zdá jasná - celá ta debata pravděpodobně posune otázku začlenění eventfd na další vývojový cyklus. Rozhraní pro uživatelský prostor jsou důležitá a je téměř nemožné je odstranit. Čekání na další verzi jádra je malá cena za to, že nakonec vývojáři rozhodnou správně.

Aktualizace: kód eventfd byl do hlavního jádra začleněn 11. května.

Potíže s volatile

link

Moje [Jonathan Corbet] vydání knihy The C Programming Language, Second Edition (copyright 1988, stále známá jako "ta nová kniha o C") o klíčovém slovu volatile [nestálý] říká toto:

Účelem volatile je vynutit implementaci, která potlačí optimalizaci, k níž by jinak došlo. Například na stroji s memory-mapped vstupem/výstupem může být ukazatel na registr zařízení deklarován jako ukazatel na volatile, aby se kompilátoru zakázalo odstranění zjevně nadbytečných referencí přes daný ukazatel.

Programátoři v C často chápou význam volatile tak, že proměnnou lze změnit mimo aktuální vlákno provádění [thread of execution]; kvůli tomu jsou občas v pokušení to použít v jádře tam, kde se využívají sdílené datové struktury. Andrew Morton nedávno poukázal na použití volatile v odevzdaném patchi:

Volatile jsou problematické - říká se, že by v jádře nikdy neměly být, ale zatím jsme nezdokumentovali proč; a i386 je vesele používá v readb() a spol.

V reakci na to shromáždil Randy Dunlap několik emailů od Linuse, kde se o tomto tématu mluví, a navrhl, jestli bych [Jonathan Corbet] nechtěl pomoci s tím "dokumentováním proč". Tady je výsledek.

Jedním z argumentů, které Linus často uvádí ve spojení s volatile, je to, že cílem je potlačit optimalizaci, což téměř nikdy nechceme. V jádře je nutné chránit přístupy k datům proti souběhům [race condition], a to je něco úplně jiného.

Stejně jako volatile, i jaderné primitivy, které souběžně přistupují k datům (spinlock, mutex, paměťové bariéry atd.), jsou navrženy tak, aby zabránily nechtěné optimalizaci. Jsou-li použity správně, není třeba používat volatile. A pokud je volatile i tak nutné, je v kódu téměř jistě chyba. Ve správně napsaném jaderném kódu může volatile akorát zpomalovat.

Představte si typický blok jaderného kódu:

    spin_lock(&zámek);
    udělej_něco_s(&sdílená_data);
    udělej_něco_jiného_s(&sdílená_data);
    spin_unlock(&zámek);

Pokud se veškerý kód řídí zamykacími pravidly, nemůže dojít k neočekávané změně hodnoty sdílená_data, dokud je držen zámek. Kterýkoliv jiný kód, který by chtěl ta data na hraní, bude muset počkat na zámek. Spinlock primitivy fungují jako paměťové bariéry - jsou tak napsány - což znamená, že přístupy k datům přes ně nebudou optimalizovány. Takže kompilátor si možná myslí, že ví, co bude ve sdílená_data, ale volání spin_lock() ho donutí všechno zapomenout. Při přístupu k těmto datům nevznikne žádný optimalizační problém.

Pokud by sdílená_data byla deklarována jako volatile, i tak by bylo potřeba zamykání. Ale kompilátoru by také bylo zabráněno v optimalizaci přístupu k sdílená v rámci té části [critical section], i když víme, že s tím nikdo jiný nepracuje. Když je držen zámek, sdílená_data nejsou volatile. A proto říká Linus tohle:

A navíc, co je důležitější, "volatile" je na špatné _straně_ celého systému. V C jsou volatile "data", ale to je šílenost. Data nejsou volatile - _přístupy_ jsou volatile. Takže by mohlo dávat smysl říct "ať je tento konkrétní _přístup_ opatrnější", ale ne "ať všechny přístupu k těmto datům používají nějakou náhodnou strategii".

Když jde o sdílená data, je při správném zamykání volatile zbytečné - a potenciálně škodlivé.

Ukládací třída volatile byla původně určena pro memory-mapped I/O registry. V jádře by i přístupy k registrům měly být chráněny zámky, ale nechceme ani, aby kompilátor "optimalizoval" přístupy k registrům v rámci dané části [critical section]. Jenže v jádře jsou I/O přístupy k paměti vždycky prováděny přes přístupové funkce [accessor]; I/O přístup k paměti přímo přes ukazatele není doporučován a nefunguje dobře na všech architekturách. Přístupové funkce jsou psány tak, aby zabránily nechtěné optimalizaci, takže i v tomto případě je volatile zbytečné.

Další situace, ve které by člověk mohl mít nutkání použít volatile, je ve chvíli, kdy je procesor zaměstnán čekáním na proměnnou. Správný způsob provedení takového čekání [busy wait]:

    while (moje_proměnná != co_chci)
        cpu_relax();

Volání cpu_relax() může snížit spotřebu procesoru nebo uvolnit místo hyperthreadovanému dvojčeti; kromě toho to také slouží jako paměťová bariéra, takže je volatile zase zbytečné. Nehledě na to, že busy-wait je tak jako tak neslušné.

Přesto existuje několik vzácných situací, ve kterých dává volatile v jádře smysl:

Většiny kódu se uvedené omluvy pro volatile netýkají. Z toho vyplývá, že použití volatile bude pravděpodobně vnímáno jako chyba, a vyslouží kódu ještě přísnější kontrolu. Vývojáři, kteří cítí pokušení volatile využít, by se měli zarazit a zamyslet se nad tím, čeho chtějí vlastně dosáhnout.

(Díky Randy Dunlapovi za to, že dal věci do pohybu a prozkoumal první případ, a Satyamu Sharmaovi a Johannesi Stezenbachovi za komentáře k první verzi toho článku.)

Související články

Jaderné noviny - 2. 5. 2007
Jaderné noviny - 25. 4. 2007
Jaderné noviny - 18. 4. 2007
Jaderné noviny - 11. 4. 2007
Nový wifi stack

Odkazy a zdroje

Kernel coverage at LWN.net: May 9, 2007

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

Jaderné noviny – přehled za duben 2024
Jaderné noviny – přehled za březen 2024
Jaderné noviny – přehled za únor 2024
Jaderné noviny – přehled za leden 2024
Jaderné noviny – přehled za prosinec 2023

Diskuse k tomuto článku

31.5.2007 08:40 Robo
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Odpovědět | Sbalit | Link | Blokovat | Admin
Ten linusov citat je genialny :))
Dalibor Smolík avatar 31.5.2007 15:50 Dalibor Smolík | skóre: 54 | blog: Postrehy_ze_zivota | 50°5'31.93"N,14°19'35.51"E
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Odpovědět | Sbalit | Link | Blokovat | Admin
V pátek jsem instaloval malý firemní server, nenaběhla mi síťová karta Attansic L1 Gigabit. Zachránilo mně až teprve jádro 2.6.21, které jako první tuhle kartu podporuje ..
Rozdíly v řeči a ve zvyklostech neznamenají vůbec nic, budeme-li mít stejné cíle a otevřená srdce.
1.6.2007 07:17 test
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Odpovědět | Sbalit | Link | Blokovat | Admin
Zaujala mne funkce cpu_relax(); Chtel jsem si ji otestovat, ale neco delam spatne, nasledujici kod vytizi CPU na 99%
#include asm/processor.h
int main(void) {
    while(1 == 1) {
        cpu_relax();
    }

    return 0; // Do budoucna
}
michich avatar 1.6.2007 07:43 michich | skóre: 51 | blog: ohrivane_parky
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
cpu_relax() nespí, takže to musí procesor plně vytížit. Ale aspoň přitom procesor neshoří, protože cpu_relax() zpomaluje jeho takt nebo vkládá nějaké čekací stavy.
Luk avatar 1.6.2007 22:14 Luk | skóre: 47 | blog: Kacířské myšlenky | Kutná Hora
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Záleží na platformě. Někde to nedělá vůbec nic (tedy jako kdyby tam volání nebylo), ale konkrétně na x86 to vkládá dvojici instrukcí (REP NOP), která ty čekací stavy vyvolává.
Šifrování je absolutní nutnost a pomáhá chránit před nekalými živly
egg avatar 1.6.2007 19:01 egg | skóre: 20 | Praha
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Misto 1==1 v podmínce stačí prostě 1. :-)
1.6.2007 20:09 test
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
aha, dekuji Vam obema =)
2.6.2007 19:27 Michal Vyskočil | skóre: 60 | blog: miblog | Praha
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
gcc (verze 4.1 a 3.4) pro while(1==1), while(1) i třeba for(;;) generuje úplně stejný assembler. Takže je to v podstatě jedno.
When your hammer is C++, everything begins to look like a thumb.
Luk avatar 2.6.2007 19:55 Luk | skóre: 47 | blog: Kacířské myšlenky | Kutná Hora
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Jenže 1 == 1 vypadá dost na palici :-D
Šifrování je absolutní nutnost a pomáhá chránit před nekalými živly
2.6.2007 21:07 Michal Vyskočil | skóre: 60 | blog: miblog | Praha
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Pro mě je na palici i ten while(1), protože neoptimalizující kompiler by zde musel tu testovací instrukci vložit. Takže pro nekonečný cyklus (pokud je by design, pochopitelně :-)) používám for(;;)
When your hammer is C++, everything begins to look like a thumb.
Luk avatar 2.6.2007 21:19 Luk | skóre: 47 | blog: Kacířské myšlenky | Kutná Hora
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Já mám k tomu ohavnému for-cyklu nějaký nepřekonatelný odpor. Proto používám while(1), resp. v C++ while(true), přestože tak záměrně spoléhám na optimalizaci kompilátoru.
Šifrování je absolutní nutnost a pomáhá chránit před nekalými živly
3.6.2007 00:09 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Já mám k tomu ohavnému for-cyklu nějaký nepřekonatelný odpor.
No tak pouzij toto:
#define ever (;;)

for ever
{
...
}
Luk avatar 3.6.2007 00:43 Luk | skóre: 47 | blog: Kacířské myšlenky | Kutná Hora
Rozbalit Rozbalit vše Re: Jaderné noviny - 9. 5. 2007
Ještě lepší, hmmm... :-(
Šifrování je absolutní nutnost a pomáhá chránit před nekalými živly

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