Portál AbcLinuxu, 5. května 2025 18:50
Aktuální verze jádra: 2.6.27-rc3. Citáty týdne: Scott James Remnant, Andrew Morton, Linus Torvalds. Spouště: méně aktivní aktivní čekání. Regulace bezdrátových zařízení. Zapleteni do vláken.
Současné vývojové jádro je stále 2.6.27-rc3. Do repozitáře hlavní řady bylo nicméně začleněno mnoho patchů, takže vydání 2.6.27-rc4 lze očekávat každou chvíli. Společně se všemi opravami 2.6.27-rc4 přidá podporu pro multitouch trackpad na nových laptopech od Apple, více stěhování include souborů specifických pro architektury, mnoho vylepšení XFS, stacky pro přerušení na architektuře SPARC64, odstranění zastaralého USB zvukového ovladače Auerswald, nové ovladače pro USB řadiče TI TUSB 6010, USB řadiče Inventra HDRC a AD převodníky National Semiconductor adcxx8sxxx.
Současné stabilní jádro 2.6 je 2.6.26.3; bylo vydáno (společně s 2.6.25.16) 20. srpna. Obě aktualizace obsahují velké množství oprav pro širokou škálu vážných problémů.
Není to poprvé, co vidím jaderné vývojáře tvrdit, že je lepší obcházet problémy v jádře v uživatelském prostoru, než je opravit. To bych pochopil, kdybychom neměli zdrojové kódy k vlastnímu jádru, ale my je máme.
Jádro není posvátné a není oddělenou částí systému. Obzvláště jeho vývojáři by ho měli považovat za jednu z komponent zcela propojené soustavy.
Naše (komplexita(konfigurační systém) * komplexita(hlavičkové soubory)) je tak velká, že testování překladem nedokazuje nic užitečného. Prostě musíte své domácí úkoly velmi pečlivě zkontrolovat a nasadit si ucpávky do uší kvůli nevyhnutelným explozím.
Chlapi, prosím: regrese jsou vážné nouzové stavy nejvyšší důležitosti. Když o nějaké slyšíme, všechno zahazujeme a běháme s hořícími vlasy (nebo ne?). Prosím, jestliže máte hlášení o regresi nebo její opravu, do Cc napište každého.
Zdá se, že věc se má tak, že si někteří lidé myslí, že začleňovací okno je čas, kdy se posílají jakékoliv náhodné hovadiny, které ani nebyly testovány, a po začleňovacím okně se posílají záležitosti, které vypadají "zjevně dobře".
Co kdybyste trochu zvýšili kontrolu kvality, abych vám nemusel nadávat? Zjevně dobré věci pošlete během začleňovacího okna a "náhodné hovadiny" neposílejte VŮBEC. A poté, během série -rc, nedělejte žádné "zjevně dobré" věci, ale "naprosto potřebné" věci.
Jaderný kód musí často čekat na to, až se jinde v systému něco stane. Preferovaným způsobem čekání je využití jednoho z mnoha rozhraní k čekacím frontám, což procesoru umožňuje ve zbylém čase vykonávat jiné úkoly. Jestliže ale zmíněný kód běží v atomickém režimu, nemůže blokovat, takže použití čekacích front nepřipadá v úvahu. Tradičně v takových situacích programátor musí napsat aktivní čekání, které sedí v těsné smyčce, dokud nedojde k potřebné události.
Aktivní čekání jsou vždy nežádoucí, ale v některých situacích to platí ještě více. Jestliže bude čekání trvat relativně dlouho, bylo by lepší přepnout procesor do stavu nižší spotřeby. Koneckonců, nikomu nezáleží na tom, jestli se smyčka vykonává plnou rychlostí, nebo jestli se dokonce nevykonává vůbec. Jestliže čekání běží ve virtualizovaném hostu, situace může být ještě horší: běh smyčky v procesoru může způsobit, že aktivní čekání může zabránit spuštění kódu, který by nakonec poskytl událost, na kterou se čeká. Ve virtualizovaném prostředí je mnohem lepší virtuální systém jednoduše úplně pozastavit, než ho nechat aktivně čekat.
Jeremy Fitzhardinge nabídl řešení tohoto problému ve formě API spouště. Spoušť [trigger] lze považovat za specifický typ čekání zamýšlený pro použití ve specifickém prostředí: v situacích, kdy je preempce zakázaná a spaní není možné, ale kde je nutné čekat na vnější událost.
Spoušť je nastavena kterýmkoliv ze dvou obvyklých způsobů:
#include <linux/trigger.h> DEFINE_TRIGGER(my_trigger); /* ... nebo ... */ trigger_t my_trigger; trigger_init(&my_trigger);
Existuje sekvence volání, kterou musí kód zamýšlející čekat na spoušť vykonat.
trigger_reset(&my_trigger); while(!podminka) trigger_wait(&my_trigger); trigger_finish(&my_trigger);
Spouště jsou navrženy tak, aby nehrozilo nebezpečí souběhů tím, že jestliže spoušť spustí po volání trigger_reset(), následující trigger_wait() se okamžitě vrátí. Jako u každého podobného primitiva jsou možná falešná "probuzení", takže je nutné ověřit podmínku, na kterou se čeká, a čekání opakovat, pokud je potřeba.
Kód, který si přeje signalizovat dokončení vláknu, které na spoušť čeká, musí pouze zavolat:
void trigger_kick(trigger_t *trigger);
Tento kód by se měl samozřejmě předtím, než trigger_kick() zavolá, ujistit o tom, že čekající vlákno bude mít k dispozici zdroj, na který čekalo.
Čtenáři obecné implementace spouští nechť je odpuštěno, pokud se zeptá, k čemu je to dobré; většina funkcí je prázdná a trigger_wait() se změní na volání cpu_relax(). Jinými slovy, je to stále aktivní čekání až na to, že je nyní schováno za sadou funkcí spouští. Zamýšleno je samozřejmě, že lepší verze těchto funkcí mohou být definovány kódem specifickým pro architektury. Pokud je cílovou architekturou například prostředí virtuálního stroje, spoušť může jednoduše stroj úplně zastavit. Za tímto účelem přichází nová sada paravirt_ops, která hypervizorům umožňuje implementovat operace spouští.
Jeremy také vytvořil implementaci pro architekturu x86, která používá relativně nové instrukce monitor a mwait. V této implementaci je spouští prostá celočíselná proměnná. Volání trigger_reset() se změní v instrukci monitor, která procesor informuje, že má dávat pozor na změnu této proměnné. Instrukce mwait zabudovaná do trigger_wait() zastaví procesor, dokud do sledované proměnné není zapsáno. Aktivní čekání již není potřeba.
Implementace pomocí monitor/mwait má svou eleganci, ale Arjan van de Ven má obavy, že by mohlo být příliš pomalé. U x86 se tedy implementace ještě může změnit. API samo o sobě nicméně příliš komentováno nebylo, takže funkce spouští se do hlavní řady mohou snadno dostat v podobě blízké té současné.
Kdykoliv linuxový systém komunikuje se zbytkem světa, musí dodržovat celou řadu pravidel toho, jak komunikaci provádět. Jednoduché TCP/IP síťování by fungovalo vskutku mizerně, kdyby se nedodržovala pravidla o tom, jak se má používat síťové médium. Pro bezdrátové síťování všechna tato omezení platí taktéž a k tomu musí dodržovat svá vlastní navíc. Protože bezdrátová rozhraní jsou rádia, musí se řídit pravidly o tom, které frekvence smí použít, jaký výkon smí vyzařovat atd. Jestli vše půjde dobře, bude mít Linux konečně centralizovaný mechanismus pro zajištění toho, že bezdrátová zařízení budou pracovat v souladu s touto širší sadou pravidel.
Předpisy o rádiovém vysílání představují problémy navíc. Jsou to zákony, takže jejich překročení může uživatelům, výrobcům a distributorům přinést nechtěné konverzace s představiteli radiokomunikačních úřadů. Zákony jsou z principu lokální, kdežto bezdrátová zařízení jsou z principu mobilní, takže zařízení musí být schopna změnit své chování, aby odpovídalo různým sadám pravidel. A některá bezdrátová zařízení mohou být naprogramována poměrně flexibilním způsobem; mohou být provozována hodně mimo své povolené parametry. Možnost, že jedno z takových zařízení může být konfigurováno - omylem nebo úmyslně - způsobem, který bude interferovat s ostatními použitími spektra, je velmi reálná.
Potenciál pro problémy se zákony spojené s bezdrátovými zařízeními vrhal nějaký čas na Linux stín. Někteří výrobci jej používali jako omluvu pro to, že nedodávají svobodné ovladače. Jiní (například Intel) přepracovali hardware tak, aby byl soulad s předpisy bezpečně zamčen ve firmwaru. A i tak měli prodejci a distributoři Linuxu obavy, jaké sankce mohou přijít, jestli někdo někde na světě přistihne linuxový systém při porušení zákona. Přes to všechno nemá linuxové jádro žádný centrální mechanismus zajišťující chod ve shodě s předpisy; je na jednotlivých ovladačích, aby zajistily, že jejich hardware pravidla neporuší. Tato situace se ale možná změní, protože sada patchů Centrální agent regulační domény [Central Regulatory Domain Agent, CRDA], kterou v současnosti vyvíjí Luis Rodriguez, se blíží k dokončení.
Jádrem CRDA je struct ieee80211_regdomain, která popisuje pravidla spojená s povoleným režimem. Je to poněkud komplikovaná struktura, ale jejímu obsahu lze porozumět snadno. Popisuje sadu povolených frekvenčních rozsahů; pro každý rozsah je uvedena maximální šířka pásma, povolený výkon a zisk antény. Také obsahuje sadu příznaků pro speciální pravidla; některé domény například nepovolují venkovní provoz nebo některé typy modulace. S každou doménou je spojen dvoupísmenný identifikační kód, který je obvykle kódem země.
V mac80211 je nová funkce, kterou může ovladač zavolat a zjistit informace o současné regulační doméně. Pokud nebude mít systém žádnou informaci o tom, kde na planetě se právě nachází, bude tato informace platná pro "světovou doménu", která je navržena tak, aby se celosvětově vyhnula porušení pravidel, a tudíž je poněkud restriktivní. Informace o poloze jsou často k dispozici od bezdrátových přístupových bodů, což systému umožňuje nastavit se bez zásahu uživatele. Jednotlivé ovladače také mohou regulačnímu jádru poskytnout "nápovědu umístění" založenou třeba na regulačních informacích zapsaných výrobcem do EEPROM zařízení. Jestliže bude potřeba, může správce systému polohu nastavit ručně.
Databáze domén a příslušných pravidel žije v uživatelském prostoru, kde může být distributory snadno aktualizována. Když je v jádře nastavena doména, generuje se událost pro udev, který je následně konfigurován, aby spustil utilitu crda. Tento nástroj použije jméno domény a vyhledá podle něj pravidla v databázi, pak použije netlink socket a předá informace zpět jádru. Odtud jsou jednotlivé ovladače informovány o nových pravidlech oznamovací funkcí.
Databáze je binární soubor, který je digitálně podepsán; jestliže podpis neodpovídá sadě veřejných klíčů zabudovaných do crda, crda ho odmítne použít. Toto chování chrání proti poškozené databázi, ale je také užitečné, protože brání uživatelům změnit databázi ručně. Žádný z distributorů ještě nezveřejnil svoji politiku, ale dá se očekávat, že podepisovací klíče pro CRDA databázi nebudou se systémem distribuovány. Jedná se zde o svobodný software, takže obejít toto omezení nebude pro středně odhodlaného uživatele problém, ale mělo by zabránit lidem snadno nastavit vysílací výkon na maximum, jenom aby zjistili, co to udělá.
Jakmile bude mechanismus CRDA začleněn do jádra a bezdrátové ovladače ho začnou používat, by měl zajistit, že linuxové systémy s hezky se chovajícími uživateli budou hezky se chovajícími vysílači. Jestli to bude dostatečné k tomu, aby byly uspokojeny regulační agentury (z nichž některé poněkud explicitně sdělily své pochyby o tom, zda může být vůbec open-source regulační kód akceptovatelný), se uvidí. V prostředí otevřeného softwaru je to ale prakticky to nejlepší, co lze udělat.
Programátoři určitého druhu jsou tak zamilováni do vláken, že jich ve svých aplikacích používají velké množství - některé aplikace vytvářejí několik tisíc vláken. Naštěstí pro tyto vývojáře - a jejich uživatele - je vytváření vláken v Linuxu poměrně rychlé. Přinejmenším většinou. Situace, kdy tomu tak není, nám dává zajímavý pohled na to, co se může stát, když se srazí škálovatelnost a historická přítěž.
Uživatel s přezdívkou Pardo si nedávno všiml, že v některých situacích se vytváření vláken na systémech x86_64 může významně zpomalit - až o dva řády. Pozoroval, že rychlost vytváření vláken je menší než 100/sekundu; při takové rychlosti se termín "poměrně rychlé" nedá použít. Pardo naštěstí udělal většinu práce potřebné k tomu, aby byl problém vystopován, čímž řešení vcelku zjednodušil.
Problém s vytvořením vlákna je v alokaci zásobníku, který se má v novém vlákně použít. Tato alokace pomocí mmap() vyžaduje několik stránek prostoru v rozsahu adres procesu. Volání mmap() může být docela časté, takže nízkoúrovňový kód, který hledá adresový prostor pro nové mapování, je napsán tak, aby fungoval rychle. Obvykle si pamatuje (v mm->free_area_cache) adresu těsně za koncem předchozí alokace, což je obvykle začátek velké díry v adresovém prostoru. Alokace dalšího místa tak nevyžaduje žádné hledání.
Volání mmap(), které vytváří zásobník vlákna, je ale zvláštní tím, že zahrnuje obskurní, pro Linux specifický příznak MAP_32BIT. Tento příznak způsobuje, že je alokace omezena na spodní 2 GB virtuálního adresového prostoru - což znamená, že ve skutečnosti by se měl jmenovat MAP_31BIT. Zásobníky vláken se udržují v dolní paměti z historického důvodu: na některých z prvních 64bitových procesorů bylo přepínání kontextu rychlejší, jestliže se adresa zásobníku vešla do 32 bitů. Aplikace, která zahrnuje tisíce vláken, nemůže být necitlivá na dobu přepínání kontextu, takže tato optimalizace stála za to.
Problém je v tom, že takto omezená alokace způsobuje, že mmap() zapomíná na mm->free_area_cache; místo toho provede lineární prohledávání přes všechny oblasti virtuální paměti [virtual memory areas, VMA] v adresovém prostoru procesu. Každý zásobník vlákna potřebuje alespoň jednu VMA, takže hledání se prodlužuje s tím, jak stoupá počet vláken.
Situace, při které se věci opravdu pokazí, nastane, když již není místo na alokování zásobníku v dolních 2 GB paměti. V takovém případě vrátí mmap() do uživatelského prostoru informaci, že selhal, a uživatelský prostor musí operaci opakovat bez příznaku MAP_32BIT. A co je horší, první volání maže mm->free_area_cache, takže druhé volání musí předtím, než je možné najít vhodný kus adresového prostoru, znovu prohledat celý seznam VMA. Není překvapující, že od té chvíle jsou věci opravdu pomalé.
Skutečně smutná věc je ale to, že zisk výkonu, který přinášelo používání 32bitových adres zásobníku, již na současných procesorech neexistuje. Ať už šlo o jakýkoliv problém, který způsoboval zpomalení přepnutí kontextu pro větší adresy, byl dávno odstraněn. Zdá se tedy, že tato konkrétní optimalizace výkonu již není optimální.
Řešení, které se zde nabízí okamžitě, je jednoduše úplně ignorovat parametr MAP_32BIT. Tento přístup by vyžadoval, aby lidé, které problém postihl, nainstalovali nové jádro, ale jinak by to bylo bezbolestné. Bohužel nikdo skutečně jistě neví, kdy postih výkonnosti pro velké adresy zásobníku zmizel či kolik stále používaných systémů může být odstraněním MAP_32BIT postiženo. Proto Andi Kleen, který toto chování implementoval jako první, argumentoval proti jeho odstranění. Také upozornil na to, že vyšší adresy by narušily optimalizaci "komprese ukazatele", kterou používají některé implementace Java virtual machine. Andi by byl raději, kdyby se lineární prohledávání VMA změnilo na něco chytřejšího.
MAP_32BIT tedy zůstává, ale alokace zásobníků vláken v dolní paměti zmizí i tak. Ingo Molnár začlenil jednořádkový patch, který vytváří nový příznak pro mmap() nazvaný MAP_STACK. Tento příznak je definován jako požadavek na oblast paměti, která je vhodná pro použití jako zásobník vlákna, ale ve skutečnosti vůbec nic nedělá. Ulrich Drepper zajistí, že glibc bude ve svém novém vydání tento příznak používat. Výsledkem je, že jakmile bude mít uživatelův systém novou glibc a opravené jádro, staré chování zásobníků zmizí a tento konkrétní výkonnostní problém bude historií.
Vzhledem k tomuto výsledku, proč prostě neignorovat MAP_32BIT v jádře a vyhnout se nutnosti upgradovat C knihovnu? MAP_32BIT je součástí ABI uživatelského prostoru a nikdo ve skutečnosti neví, jak ho někdo může používat. Porušení ABI není možné, takže staré chování musí zůstat. Na druhou stranu argumentem pro odstranění MAP_32BIT při vytváření zásobníků vláken je to, že by nebylo nutné aktualizovat jádro. Jak se tak stává, změna na MAP_STACK bude mít efekt stejný; starší jádra, která tento příznak neznají, ho budou jednoduše ignorovat. Jestliže se ale v budoucnosti ukáže, že tento výkonnostní problém se zásobníky ve vyšší paměti na reálných systémech stále existuje, jádro lze vyladit tak, že implementuje staré chování, pokud bude běžet na postiženém procesoru. Takže budeme-li mít štěstí, všechny mety jsou pokryty a tato záležitost se již nevrátí.
Dekuji.Musím zklamat se slovy "není zač". Tam, kde český překlad dává smysl, tam budu překládat...
Asi přestanu českou literaturu brát na zřetel.S predchozim souhlasim a k citaci dodam toto - ceskou literaturu beru az jako uplne posledni moznost.
běžné zažité anglické termínyNo a to je právě ono. Kdyby před X lety někdo nezačínal říkat a psát roura, vlákno, nebo ovladač, tak se tu dnes rozčilujete nad knihou, kde si dovolí překládat pipe, thread, nebo driver. A tak by se dalo pokračovat dál. Uznávám, že překládat carry je spíše nedostatek odborných znalostí, než snaha o tvorbu nové české elektrotechnické terminologie. To ovšem nic nemění na tom, že "běžně zažitý" je dost fuzzy pojem. I běžně zažitý pojem musí (v češtině) někdy zářit novotou, než se z něj (možná*) stane ten běžně zažitý. * ono je důležité, aby byl český pojem taky libozvučný a pomáhá, když bude i kratší, než anglický termín. Odstrašujícím příkladem je SŘBD, který používají snad jenom někteří akademici, nebo lidé, co chtějí poukázat na odstrašující příklad české terminologie
Čeština je pro IT mrtvá...Akorát by mě zajímalo, proč si někdo s takovým postojem dělá vrásky kvůli jednotlivým drobnostem v českém překladu LWN...
Čeština je pro IT mrtvá...Možná bych raději řekl, že lidi s podobným názorem jsou mrtví pro češtinu…
Čeština je pro IT mrtvá...Proč to píšete pod české Jaderné noviny? Jaderné noviny mají zjevně dost čtenářů, takže pravděpodobně existuje dost lidí, kteří je chtějí číst česky. Pokud někomu vyhovují anglické termíny, nic mu nebrání, aby si četl originální články v angličtině.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.