Portál AbcLinuxu, 5. května 2024 18:16

Jaderné noviny – 12. 1. 2010

5. 2. 2010 | Jirka Bourek
Články - Jaderné noviny – 12. 1. 2010  

Aktuální verze jádra: 2.6.33-rc4. Citáty týdne: Casey Schaufler, Greg Wettstein. Časovače s volností. Konec nastavování režimu z uživatelského prostoru? sys_membarrier() a RCU v uživatelském prostoru. FBAC-LSM: Omezování aplikací založené na funkcionalitě. Spekulace o výpadcích stránek.

Obsah

Aktuální verze jádra: 2.6.33-rc4

link

Současné vývojové jádro je 2.6.33-rc4 vydané 12. ledna. Hmm. Podivné vydání. Kolem 40 % patchů je v DRM (většinou nouveau a radeon, oba jsou ve staging, takže je to o něco méně děsivé, než se zdá. Také je tam ale významná část týkající se i915.) To je všechno poměrně neobvyklé. Také je zde pár nových nízkoúrovňových ovladačů, podpora pro jádra komprimovaná LZO a nová obecná funkce pro řazení list_sort(). Všechny detaily lze nalézt v kompletním changelogu.

Stabilní aktualizace: Jediná aktualizace stabilních jader byla tento týden 2.6.31.11 vydaná 7. ledna, která opravovala chybu při překladu zavedenou v 2.6.31.10.

Citáty týdne: Casey Schaufler, Greg Wettstein

link

Dnešní uživatelé počítačů jsou mnohem méně připraveni na práci s aplikacemi, které se chovají jinak, protože znenadání přestala fungovat síť. To je proto, že jak programátor, tak uživatel očekávají, že síť bude k dispozici, protože vždycky je. Nikdy nevyzkouší situaci, kdy síť nefunguje, a programy, které používají/píší, pravděpodobně situaci nezvládnou. Jsou to lenoši.

-- Casey Schaufler

Doufám, že tohle všechno pomůže, protože ať už se zde ladí jakékoliv chování, na tomto kalibru hardwaru jsou nejnovější jádra problematická. A to nemluvím o důsledcích, které to má na moji zadní část, když moje milovaná nemůže hrát ,Blast the Bubbles‘ tak, jak by chtěla.

-- Greg Wettstein mění definici „kritické pro nasazení“.

Časovače s volností

link

Jedním z nejlepších způsobů, jak snížit spotřebu energie systému, je vyhnout se probouzení CPU, pokud je to možné. Omezení počtu probuzení je zajištěno tak, že časovače vyprší naráz, když má smysl to tak udělat. Probudit procesor jednou, aby obsloužil dva časovače, je mnohem efektivnější, než řešit dvě oddělené obsluhy. Zajistit takovou obsluhu nicméně většinou vyžaduje upravit dobu, za jakou má časovač vypršet. U standardních (ne těch s vysokým rozlišením) jaderných časovačů lze tuto úpravu provést pouze funkcí round_jiffies(), která intervaly vypršení upraví na hrubší časové jednotky s tím, že snad budou časy vypršení častěji stejné. Tato metoda do určitého rozsahu funguje, ale vyžaduje změny kódu všude, kde se používají časovače.

Arjan van de Ven navrhl vylepšení API časovačů – nazvané časovače s volností [timer slack] – které by měly zjednodušit shlukování událostí časovače. Zjednodušeně přidává určitý interval, ve kterém může časovač vypršet, což jádru dává určitou flexibilitu v tom, jak jsou časovače plánovány. Tento interval se nastavuje funkcí:

void set_timer_slack(struct timer_list *timer, int slack_hz);

V podstatě to říká, že vypršení časovače naplánované daným timer je možné zpozdit až o slack_hz jiffies. Ve výchozím nastavení je volnost nastavena na 0,4 % doby vypršení časovače – což je velmi konzervativní hodnota. Když je časovač naplánován, skutečný čas vypršení je určen pomocí jednoduchého algoritmu, který vybere dobře definovaný čas v intervalu volnosti.

Výhodou tohoto přístupu je, že zjednodušuje shlukování událostí časovačů z několika zdrojů bez nutnosti měnit kód na všech místech volání. Další flexibility je možné dosáhnout zvýšením volnosti u specifických často používaných čítačů, ale i bez toho by měly časovače s volností na mnoha systémech zlepšit efektivitu spotřeby energie.

Konec nastavování režimu z uživatelského prostoru?

link

Je to již rok od doby, co se do hlavní řady dostalo jaderné nastavování režimu [kernel mode setting, KMS]. KMS přesouvá řízení nízkoúrovňových režimů grafických procesorů do jádra, pryč od ovladačů v uživatelském prostoru, což s sebou přináší mnoho dalších výhod. KMS zpočátku podporoval pouze ovladač Intelu, ale svou cestu si kód našel i do ovladačů Radeon a Nouveau. Vývojáři nyní mluví o úplném odstranění nastavování režimu z uživatelského prostoru.

Na straně Nouveau Ben Skeggs zaslal patch, který odebírá podporu pro běh bez KMS:

Patche pro běh bez KMS jsou zaneřáděné a, řekněme si to na rovinu, hrozně hnijí. IMO je kód KMS dostatečně stabilní, abychom mohli jít dál bez berličky UMS, navíc kód KMS podporuje mnohem více čipových sad (konkrétně GF8 a vyšší), které kód UMS nikdy podporovat nebude.

Hlavní námitkou proti odstranění tohoto kódu bylo, že systémy založené na BSD nepodporují KMS, ale současný ovladač na těchto systémech beztak nefunguje. Takže i když si tento patch do hlavní řady cestu nenašel, nepřekvapilo by, kdyby se tak stalo před vydáním 2.6.34.

Přibližně ve stejné době se někteří vývojáři z Intelu začali ptát, jestli by bylo možné zahodit podporu pro běh bez KMS. I zde se zdá, že kód pro nastavování režimu z uživatelského prostoru není příliš oblíben a je těžké ho udržovat. Vypadá to nicméně, že tento kód bude nezvaným hostem ještě nějakou dobu; Linus nijak nechvátá s jeho odstraněním a Dave Airlie má ještě větší námitky:

Jsem pro až dva tři roky nejmíň a musí být alespoň jedno jádro bez vážných regresí v KMS Intelu, k čemuž jsme se ani nepřiblížili. Nejsem si ani jistý tím, že lidi od Intelu berou slovo stabilní dostatečně vážně. Zatím si nemyslím, že by existovalo jediné vydání jádra (i stabilní), které by fungovalo se všemi čipovými sadami od Intelu bez backportování patchů.

Odstranění podpory pro běh bez KMS z ovladače Intelu je tedy brzděno obavami o stabilitu kódu KMS. Zde je ale i větší problém: Podpora pro Intel byla v jádře již několik let, takže je spousta systémů, které na nastavování režimu z uživatelského prostoru závisí. To znamená, že tuto podporu je nutné udržovat dost dlouho, aby s jistotou nedošlo k rozbití těchto systémů. Nouveau má naopak výhodu v tom, že v hlavní řadě až doteď nebylo, takže obavy z regresí není třeba řešit. Někdy je výhodné přijít pozdě.

sys_membarrier() a RCU v uživatelském prostoru

link

Mathieu Desnoyers je dlouhou dobu vývojářem sady nástrojů pro sledování LTTng. Jeho současný projekt se zabývá poskytnutím možnosti rychlého sledování vícevláknových aplikací v uživatelském prostoru; to vyžaduje rychlý a vícevláknový sledovací nástroj. Sledování je řízeno sdílenou oblastí v paměti; aby bylo řízení co nejrychlejší, chtěl by Mathieu použít algoritmus čtení-kopírování-aktualizace [read-copy-update, RCU]. Z toho důvodu pracoval na portování RCU – technologie, která je jenom v jádře – do uživatelského prostoru. A přitom narazil na nějaké zajímavé problémy.

Stejně jako u jaderné verze funguje RCU v uživatelském prostoru tak, že odloží úklid objektů v paměti do doby, dokud není jisté, že se na tyto objekty nikdo neodkazuje. Implementaci je nicméně potřeba udělat jinak, protože kód v uživatelském prostoru nemůže běžet v atomickém režimu, který používá RCU v jádře. V uživatelském prostoru tedy volání rcu_read_lock() nastaví proměnnou ve sdílené paměti, která říká, že vlákno je v kritické sekci RCU a tedy že může bezpečně přistupovat k proměnným chráněným RCU.

…tedy alespoň v případě, kdy nikdo nezměnil pořadí operací tak, že přístup k proměnné chráněné pomocí RCU proběhne před tím, než se rcu_read_lock() projeví na všech ostatních CPU. Tato změna pořadí operací se může objevit snadno, a to jak na úrovni překladače, tak na úrovni CPU, takže jde o problém, který je nutné řešit. Změně pořadí operací při překladu se lze vyhnout poměrně snadno, ale změně pořadí v CPU je potřeba zabránit instrukcí pro paměťovou bariéru. Do volání rcu_read_lock() lze tedy vložit paměťové bariéry a tím RCU v uživatelském prostoru zprovoznit.

Problém tohoto řešení spočívá v tom, že paměťové bariéry věci významně zpomalují. A co je horší, zpomalují i rychlou cestu v případě změny proměnné chráněné RCU – což se často nestává. Mathieu by se tedy této bariéry rád zbavil. Za tímto účelem napsal řešení, které vyšle všem vláknům signál, když se má proměnná chráněná RCU měnit, čímž všechna vlákna donutí vykonat paměťovou bariéru. Věřte tomu nebo ne, toto řešení věci zrychlí, ale signály téměř nikdy nejsou optimálním řešením, ať už jde o jakýkoliv problém. Mathieu by radši něco lepšího.

Jako „něco lepšího“ se nakonec ukázalo jednoduché systémové volání:

void membarrier()

Původní implementace jednoduše vyslala meziprocesorové přerušení na všechna CPU v systému; přijímající CPU by vždy zareagovalo vykonáním explicitní instrukce pro paměťovou bariéru. Toto řešení fungovalo, ale během revizí narazilo na několik námitek:

Následovala dlouhá diskuze o tom, jak patch optimalizovat, jestli je explicitní paměťová bariéra zapotřebí i poté, co CPU přijalo meziprocesorové přerušení (bezpečná odpověď je podle všeho „ano“), a tak dál. Shrnuto – optimalizaci malého patche, který ve svém jádře implementuje pomalou cestu, která by se měla vykonávat jenom občas, bylo věnováno obdivuhodné množství práce.

Současný stav je takový, že Mathieu zaslal novou verzi patche s mnoha změnami. První je přidání celočíselného parametru expedited. Jestliže je jeho hodnota nulová, systémové volání jednoduše zavolá synchronize_sched() a vrátí se; to je nejlevnější cesta, kterou lze získat potřebnou funkcionalitu, ale za cenu latence několika milisekund pro volajícího. Je zjevné, že Mathieu očekává, že se režim „expedited“ – urychlený – bude používat ve většině případů.

U urychlené bariéry se systémové volání podívá na každé CPU v systému a vytvoří masku těch, které běží ve stejném adresovém prostoru jako volající; tato CPU poté obdrží meziprocesorové přerušení, které je požádá, aby vykonaly instrukci pro paměťovou bariéru. Je to o něco komplikovanější implementace, ale vzhledem k tomu, že přerušuje jenom procesory, na kterých běží volající aplikace, obavy z odepření služby, výkonnosti a spotřeby energie nejsou nadále relevantní. Lze předpokládat, že patch se blíží své konečné podobě, ale těžko to říct s jistotou: někdy jsou ty nejmenší a nejjednodušší patche zkoumány nejpodrobněji.

FBAC-LSM: Omezování aplikací založené na funkcionalitě

link

Bezpečnostním pískovištím [sandbox] pro procesy se v dnešní době dostává mnoho pozornosti. Existují samostatné nástroje jako isolateRainbow, pískoviště integrovaná do aplikací jako pískoviště v Chromium, stejně jako nástroje, které používají existující LSM [Linux Security Module, bezpečnostní modul pro Linux], jako je pískoviště SELinux. Kromě toho okolo poletují návrhy přidat do linuxového jádra vlastnosti podporující pískoviště pro aplikace, jako jsou rozšíření seccompomezení sítě. LSM specificky navržený k uzavírání aplikací do pískoviště, který používá nový model nazvaný „Omezování aplikací založené na funkcionalitě“ [Functionality-Based Application Confinement, FBAC] byl na linux-kernel představen v prosinci.

FBAC-LSM vzešel z výzkumné práce při PhD studiu, jejímž autorem je Z. Cliffe Schreuders, a je prototypem implementace modelu FBAC. Používá starší verzi rozhraní LSM s háčky založenými na cestě [pathname] AppArmoru a stále potřebuje poměrně dost práce, než bude připraven pro produkční systémy nebo formální revizi kódu. Schreuders hledá spolupracovníky, kteří by se s ním věnovali dokončení projektu, pravděpodobně s cílem dostat ho do hlavní řady.

Základní myšlenou FBAC je zajistit, aby byly bezpečnostní politiky přístupnější a pochopitelnější pro uživatele, aby bylo šířeji přijímáno omezování aplikací. Hlavní komponentou systému FBAC je správce politik s grafickým uživatelským rozhraním, který uživatele provází nastavením politik pro konkrétní aplikace. Uživatelé specifikují vysokoúrovňové potřeby aplikace podle jejího typu (například prohlížeč webu nebo editor souborů) a správce politiky pomůže vytvořit politiku, která bude řídit chování této aplikace.

Při vývoji správce politiky Schreuders analyzoval přes sto různých aplikací, aby zjistil obvyklá chování, která by bylo možné obalit politikami FBAC. To správci umožňuje zautomatizovat určité aspekty vývoje politik pro nové aplikace, včetně věcí, jako jsou konfigurační soubory, síťové porty a další zdroje, které aplikace potřebuje. Správce politiky také obsahuje „režim učení“, ve kterém pozoruje aplikaci a navrhuje dodatečná oprávnění, která by jí bylo možné přidělit.

FBAC obsahuje koncept „funkcionalit“, což je v podstatě sada oprávnění pro povolené operace se sítí a se soubory. Jedná se o jemně dělené záležitosti jako „file_read“, „file_getattr“, „file_execute“, „dir_mkdir“, „network_incoming“ atd. Oprávnění, která jsou udělena konkrétní funkcionalitě, jsou vyjmenována v její definici.

Funkcionality jsou hierarchické, takže mohou zahrnovat další oprávnění na nižší úrovni do jedné, která následně řídí celou aplikaci nebo celou třídu aplikací. Krom toho jsou parametrizované, takže lze jednu funkcionalitu aplikovat na více různých aplikací, přičemž parametry specifikují konkrétní soubory, adresáře a místa v síti, pro která jsou oprávnění udělena.

FBAC podporuje jak povinné řízení přístupu [mandatory access control, MAC], tak volitelné řízení přístupu [discretionary access control, DAC]. Politiku pro aplikace může nastavit administrátor, takže běžný uživatel nemůže dělat žádné změny, nebo lze FBAC nakonfigurovat tak, že je uživatelům umožněno omezit aplikace více, než určují politiky nastavené administrátorem. Omezení aplikace poté závisí na průniku povinných a volitelných politik.

Tím, že se uživatelům umožní specifikovat omezená privilegia pro libovolnou aplikaci, se objevuje stejné riziko problémů se setuid() programy, na které narazily jiné mechanismy pro uzavření aplikace na pískoviště (například vlastnost pro omezení přístupu k síti zmíněná výše). Je potřeba poskytnout nějaké prostředky, aby se neprivilegovaným uživatelům zabránilo měnit prostředí, které setuid() programy očekávají.

Rozhraním pro konfiguraci FBAC-LSM je souborový systém připojený do /sys/kernel/security/fbac-lsm. Soubory v tomto adresáři umožňují dotazovat se na aktuálně nainstalované politiky a přidávat nové. Zaslání informací o politice má několik kroků, každý kousek se zapisuje do odděleného souboru v adresáři. Následuje zápis „commit“ do /sys/kernel/security/fbac-lsm/commit, což vyvolá zpracování politiky. To je poněkud náchylné k souběhům, ale je to nutné kvůli pravidlu „jedna hodnota na soubor“ platnému pro sysfs. Je dost pravděpodobné, že se rozhraní FBAC-LSM změní na privátní souborový systém podobný těm, které používá Smack a SELinux.

FBAC používá odlišný přístup než jiná řešení zaměřená na bezpečnost, ale některé části jsou dost podobné, takže Schreuders plánuje naprogramovat správce politiky tak, aby četl a zapisoval politiky pro AppArmor a SEEdit. FBAC nicméně vypadá tak, jak se od prototypu dá očekávat – kód je poměrně neorganizovaný a zaneřáděný zakomentovanými sekcemi, kvůli kterým je poměrně těžké ho číst.

Současná inkarnace FBAC-LSM rozhodně vzbuzuje pocit, že byl kód sestaven poměrně ve spěchu kvůli dizertační práci PhD, a ne jako „skutečný“ LSM. Obsahuje ale několik zajímavých nápadů, které si zaslouží další pozornost. Jednou z největších překážek, které čelí různá bezpečnostní řešení (nejlepším příkladem je SELinux), je složitost vývoje a - což je důležitější – pochopení politik, které se používají. Tato složitost je něco, co se Schreuders rozhodl s pomocí FBAC omezit. Ještě se uvidí, jestli uspěje, ale každý takový pokus stojí za pozornost.

Spekulace o výpadcích stránek

link

Zlepšení výkonnosti jádra je obecně dobrá věc; to je důvod, proč mnoho z našich nejlepších vývojářů věnovalo významné množství času práci na optimalizaci. Jedna z oblastí, které se nedávno dostalo pozornosti, je řešení měkkých výpadků stránek. Jak ale tato práce ukázala, problémy s výkonností nejsou vždy tam, kde si člověk myslí, že jsou; někdy je nutné udělat krok zpět a situaci zhodnotit znova a možná přitom vyhodit spoustu kódu.

Výpadky stránek mohou být poměrně drahé, obzvláště pokud se jedná o ty, které je nutné řešit čtením dat z disku. Na typickém systému nicméně bude spousta výpadků stránek, které I/O vyžadovat nebudou. Výpadek stránky typicky nastává, když specifický proces nemá platný záznam v tabulce stránek pro potřebnou stránku, ale tato stránka často bývá v cache stránek; v takovém případě obsluha výpadku spočívá v jednoduché opravě tabulky stránek a zvýšení počtu odkazů na danou stránku; to se často děje u sdílených stránek nebo u těch, které byly načteny při dopředném čtení [readahead]. Výpadky nových anonymních stránek (většinou data a zásobník aplikací) lze řešit alokací stránky vyplněné nulami. V obou případech je výpadek vyřešen rychle a není potřeba se obracet na úložné zařízení.

U mnoha pracovních zátěží tento druh „měkkých“ výpadků nastává mnohem častěji než tvrdé výpadky vyžadující skutečné I/O. Je tedy důležité, aby byly vyřešeny rychle. Různí vývojáři se shodli na tom, že jádro tento druh výpadku neřeší dostatečně rychle, a jako hlavní příčinu problému identifikovali semafor čtenář/zapisovatel [reader/writer] mmap_sem. V tomto případě nebylo problémem soupeření – při obsluze výpadku stránky se zabírá pouze čtecí zámek – ale poskakování řádku v cache způsobené neustálým zabíráním zámku výkonnost zabíjelo. A jak se počet jader v systému zvyšuje, tento problém se může jenom zhoršovat.

V reakci na to Hiroyuki Kamezawa zaslal v listopadu první patch pro spekulativní výpadky stránek. Základní myšlenkou tohoto patche je pokusit se vyřešit obsluhu výpadku stránky úplně bez zabírání mmap_sem. To samozřejmě znamená riziko souběhů; konkrétně se během práce může změnit struktura vm_area_struct (VMA), která řídí mapování paměti. Kód spekulativního řešení výpadku tedy musí výpadek vyřešit, poté zkontrolovat, jestli nedošlo k nějakým souběžným změnám, a v případě potřeby práci zopakovat starším a pomalejším způsobem. To je ta „spekulativní“ část: Odvedení práce bez zámků, přičemž se doufá, že svět se mezitím nezmění a nevynutí tím nutnost tuto práci zopakovat.

Kód pro spekulativní řešení výpadků také musí zajistit, že během řešení výpadku nedojde k žádným změnám, které by způsobily opravdové potíže (jako je například úplné uvolnění VMA). Za tímto účelem různé verze patche zkoušely techniky jako přidání čítání odkazů do struktury VMA nebo používání čtení-kopírování-aktualizace [RCU] s kódem červeno-černých stromů (které se používají k alokaci VMA pokrývající specifickou adresu v adresovém prostoru) – tím se měly změny odložit, dokud spekulativní kód nedokončí svou práci.

Z této práce vzešly skutečné výsledky: Počet výpadků stránek za jednotku času, které systém dokázal zvládnout, když na něm běžel benchmark zaměřený na výpadky stránek, se přibližně zdvojnásobil. Nápad tedy zjevně měl opodstatnění, ale Peter Zijlstra měl pocit, že patche od Kamezawa-san nebyly dostatečně bláznivé. Rozhodl se tento problém napravit svými vlastními patchi pro spekulativní výpadky stránek, které se také dočkaly mnoha revizí. Peterův přístup zahrnoval přidání zámků pro spekulativní tabulky stránek a pro správu struktur VMA použil RCU. Výsledkem byl patch, který „občas nabootoval“ a který, zdálo se, zlepšoval výkonnost.

V tu chvíli se do věci zapojil Linus, poukázal na nějaké problémy Peterova patche a došel k závěru:

Řekl bych, že celá tato série má k začlenění _hodně_ daleko. Peter podle všeho přemýšlel o detailech, zatímco přehlédl všechny jemné vlivy na celkový obraz, které podle všeho mění sémantiku.

Peter s tímto závěrem souhlasil s poznámkou, že si nikdy nemyslel, že by patche byly připraveny.

V další diskuzi si Linus, když se podíval na profil aktivity při řešení výpadků stránky, všiml něčeho zábavného: Skutečnou režii podle všeho tvořily operace se spinlocky, které by se v optimalizované implementaci rwsem pro x86 neměly vůbec objevit. Ukázalo se, že zmíněná optimalizace byla aplikována pouze na 32bitové systémy; na překladech pro 64bitové semafory čtenář/zapisovatel používaly obecné implementace založené na semaforech. To znamená, že byly mnohem pomalejší, než by mohly být.

Linus tedy nadhodil novou implementaci rwsem založenou na x86 instrukci vyměň a sečti (exchange-and-add, xadd) s typickým varováním:

Jinými slovy: NETESTOVÁNO! Může vám to znásilnit domácí mazlíčky a vypít všechno pivo. Varováni jste byli.

Kamezawa-san statečně nový kód vyzkoušel a dospěl k zajímavému výsledku. Jeho domácí mazlíčci a pivo přežili bez úhony – a výkonnost při výpadcích stránky byla lepší než s jeho patchem pro spekulativní řešení výpadků stránek. I Peter zkusil několik testů proti vlastnímu spekulativnímu kódu; tyto testy ukázaly, že změna rwsem výkonnost ztrojnásobila. Jeho patch pro spekulativní řešení výpadků výkonnost zlepšil ještě o něco málo více a oba dohromady ještě o něco více. Patch rwsem je ale malá a jasná oprava, zatímco patch pro spekulativní výpadky je velký, rozsáhlý, děsivý a obsahuje problémy. Nikdo tedy nezpochybnil Peterův závěr:

Takže i když si myslím, že používat tyto spekulativní výpadky je možné, zdá se, že na ně ještě nejsme úplně připraveni.

V době psaní tohoto článku nikdo nezaslal konečnou verzi patche rwsem. Linus poznamenal, že by se na něm dalo pár věcí vylepšit, ale bylo by pro něj typické, kdyby tuto práci nechal na jiných. Dá se ale předpokládat, že nějaká verze tohoto patche bude čekat na otevření začleňovacího okna 2.6.34. Bude to jasnou ukázkou toho, že i v našem vysoce optimalizovaném jádře existuje nízko visící ovoce v podobě zlepšení výkonnosti; stačí se podívat na správné místo.

Související články

Jaderné noviny – 5. 1. 2010
Jaderné noviny – 23. 12. 2009
Jaderné noviny – 16. 12. 2009
Jaderné noviny – 9. 12. 2009

Odkazy a zdroje

Kernel coverage at LWN.net: January 12, 2010

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

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