Linux E X P R E S

Facebook

Dvacet let Linuxu: Aktuální dění v jádře

20let.png

Sérii článků o linuxovém jádře uzavírá přehled toho, co se děje „právě teď“, tedy zhruba v posledním čtvrtroce. Vývojáři živě diskutují o tom, co do jádra přidat, co tam změnit nebo přepracovat, případně co odebrat. Výsledkem tohoto procesu často bývá nová technologie či funkce v jádře nebo nějaká změna toho, co už tam je. Podívejme se tedy na život Linuxu v posledních týdnech až měsících. Vybraná témata jsou seřazena chronologicky, od nejstaršího k nejčerstvějšímu.


Problémy s přednačítáním do cache CPU

V jádře je k dispozici funkce prefetch(), která pomocí speciální instrukce vyžádá přednačítání dat do cache. Používá se dost hojně, např. při práci se spojovými seznamy. Andi Kleen a později i Linus Torvalds však zjistili, že použití přednačítání výkon nezvyšuje, nýbrž naopak snižuje. Ingo Molnár naměřil zpomalení asi o půl procenta. Současné procesory zřejmě optimalizují své přednačítání natolik kvalitně, že řešení na úrovni softwaru působí kontraproduktivně. Výsledkem zjištění bylo odstranění prefetch() z procházení spojových seznamů, hlist a seznamů sk_buff, a to od jádra verze 2.6.40.

Diskuze o vsyscallech a vDSO

Některá volání jádra lze (přinejmenším na určitých architekturách) zajistit bez nutnosti skutečného vstupu do jádra. Místo toho stačí namapovat paměťovou stránku ke čtení do uživatelského prostoru; ušetří se tím režie systémového volání. Používají se dva způsoby: starší vsyscall (s pevným umístěním v paměťovém prostoru) a novější vDSO (s randomizovaným umístěním). Vsyscall může svým charakterem napomoci některým útokům. Proto Andrew Lutomirski navrhl, že se z vsyscall odeberou výkonné instrukce a příslušná virtuální volání se nechají realizovat pomocí skutečných systémových volání, tedy i s režií navíc, ale bez možnosti zneužití k útoku. Linus Torvalds však není nakloněn takové změně, pokud by byla bezpodmínečná nebo pokud by příslušná konfigurační volba v jádře označovala starou implementaci jako nebezpečnou. Problém je zatím s knihovnou GNU C, která donedávna používala v případě volání time() ještě stále vsyscall. S postupným pronikáním nové verze knihovny do distribucí by měl ale problém se závislostí na vsyscall postupně vymizet.

Přizpůsobení jmen zařízení

V současnosti se jména zařízení přiřazují podle pořadí detekce. U disků a diskových oddílů se běžně používají i další pojmenování, ta jsou ale záležitostí udev, který vytváří odkazy. Nao Nishijima navrhl řešení, které umožňuje přidat ke každému zařízení jeho preferovaný název. Návrh se nesetkal s příliš velkým pochopení, a to z více důvodů. Patří mezi ně funkční problémy (spojené např. se změnou za provozu), ale i „nesystematičnost“ z hlediska komplexního řešení logování informací.

Problémy s logy jádra

Logování událostí v jádře se potýká s různými problémy. Jedním je potenciální přítomnost nebezpečných znaků, které mohou ovlivnit způsob zobrazování a skrýt tak (na popud útočníka) například informace svědčící o provedeném útoku. Nepanuje shoda na tom, jak to řešit – navrhují se blacklisty, whitelisty i ponechání v současném stavu (s tím, že se filtrace zajistí v uživatelském prostoru).

Dalším problémem logování je nestrukturovanost. Běžně používaná funkce printk() neposkytuje žádné prostředky pro strukturování zpráv. Existují úvahy ohledně použití něčeho podobného, jako se používá pro uevent. Společná řeč však ani v tomto případě nebyla nalezena, a tak problém zůstává nevyřešen.

Bezpečnostní problém: RLIMIT_NPROC a setuid()

Limit RLIMIT_NPROC omezuje počet procesů vlastněných daným uživatelem. Pokud se zavolá setuid() pro změnu uživatele a limit je překročen, volání selže. To je vážný bezpečnostní problém u programů, které nekontrolují návratovou hodnotu setuid(), a proces tak dál běží s vyššími privilegii (jako root, resp. podle kvalifikací, které mu zůstávají). Byla diskutována různá použitelná řešení, včetně posílání signálu při selhání nebo přesunu kontroly do execve(). Zatím nebylo nalezeno optimální řešení, nicméně Linus Torvalds se každopádně přiklání k tomu, aby se limit na počet procesů v setuid() nekontroloval.

NAT v IPv6

Terry Moës vytvořil linuxovou implementaci NAT pro IPv6, podporující bezestavové i stavové chování. Jde o věc navýsost kontroverzní, protože nemálo lidí NAT pro IPv6 odmítá. Jiní, například David Miller, však tvrdí, že NAT v IPv6 bude, protože o něj je velký zájem. Zatím ale nejsou signály, že by byl takový kód brzy začleněn do jádra.

Obecná podpora pro zařízení s NFC

V jádře verze 3.1 se v síťové vrstvě objevila obecná podpora pro zařízení s near-field communication (NFC). Nový subsystém NFC je založen na dvou mechanismech. Jednak je to socket PF_NFC (s protokolem NFC_SOCKPROTO_RAW) pro přímou nízkoúrovňovou komunikaci se zařízeními. Pro ovládání pak slouží komunikace přes netlink. Na ovladačích konkrétních zařízení je pak implementovat pět callbacků rozhraní využívaného subsystémem.

lseek() nyní implementuje SEEK_HOLE a SEEK_DATA

O zavedení příznaků SEEK_HOLE a SEEK_DATA (tj. hledání děr, resp. dat v souboru) volání lseek() do Linuxu se hovoří už více než 5 let. Příznaky byly zavedeny v systému Solaris v souvislosti se souborovým systémem ZFS (první pokusy o linuxovou implementaci byly zhruba o rok později). Linux se konečně dočkal ve verzi 3.1. Cílem je poskytnout optimalizaci pro účely komprese dat (bez nutnosti přenášet data do uživatelského prostoru).

Řešení problémů SKB fragmentů

S buffery odkazovanými přes struktury sk_buff mohou být potíže v případech, kdy nastávají problémy v síťové vrstvě a vyšší úroveň nemá šanci zjistit, co všechno síťová vrstva se strukturami a odkazovanými buffery prováděla. Může se tak stát, že se stránka používaná síťovou vrstvou přepíše jinými daty. Řešení znamená poměrně významné zásahy do existujícího kódu. Kromě jiného zavádí fragmentové destruktory, které s využitím počitadla referencí zajistí uvolnění bufferového fragmentu až po skončení všech operací. Při posílání paměťové stránky po síti pak bude možné nastavit tento destruktor. V implementaci Sun RPC bylo třeba také zamezit indikaci dokončení operací, dokud probíhá práce s takto alokovanou pamětí.

Nové možnosti volání ptrace()

V Linuxu 3.1 přibyly u volání ptrace() nové příkazy. Je to PTRACE_SEIZE (funguje jako PTRACE_ATTACH, tedy připojí se k procesu, ale nezastaví program ani nemění obsluhu signálů), PTRACE_INTERRUPT (zastaví proces; určeno pro procesy připojené pomocí PTRACE_SEIZE) a PTRACE_LISTEN (i zastavený proces obdrží některé události). Cílem je, aby mělo ladění co nejmenší dopady na laděný proces.

Sdílení bufferů mezi zařízeními

V současnosti je často možné (a žádoucí), aby zařízení v systému komunikovala přímo mezi sebou, aniž by data musela procházet přes aplikaci v uživatelském prostoru (ale přitom aby taková aplikace přenosy mohla řídit). K tomu však tato zařízení potřebují paměť, přes kterou budou komunikovat. Proto vznikla implementace (zatím jen jako proof-of-concept), která takovou komunikaci přes sdílený paměťový buffer umožňuje. S bufferem se pracuje s využitím počitadla referencí (aby byl buffer automaticky zrušen v okamžiku, kdy už ho nikdo nepotřebuje). Bufferu je přiřazen souborový deskriptor, který se z jádra poskytne do uživatelského prostoru.

Native Linux KVM Tool – kontroverze

Native Linux KVM Tool (NLKT) je emulace hardwaru umožňující běžet virtuálním strojům pod hypervizorem KVM. Nyní se intenzivně řeší, zda tento kód, který běží v uživatelském prostoru, začlenit do repozitáře jádra či nikoli. Linus Torvalds zatím (pro Linux 3.1) začlenění odmítl, jinak jde ale v podstatě jen o jeden konkrétní případ dlouhých obecných diskusí ohledně toho, co všechno (z věcí běžících v uživatelském prostoru) začlenit do repozitářů jádra a spravovat společně s ním. Řeší se i samotný název, a to nejen u NLKT, ale i samotné technologie KVM, kdy se tato zkratka může snadno plést s přepínači klávesnic, monitorů a myší.

ABI systémových volání x32

V současné době mohou aplikace na 64bitové architektuře x86 běžet ve dvou režimech: nativním 64bitovém a kompatibilním 32bitovém. Vznikl ale návrh třetí cesty, x32. Ta má nabídnout běh v 64bitovém režimu, ale s 32bitovými adresami a proměnnými. Problém je zde se systémovými voláními – některá současná 64bitová nelze přímo použít, proto je součástí návrhu přidání nových volání. Ostře proti se staví Linus Torvalds, který kritizuje jednak přidávání nových volání, ale také zanášení starých problémů s nedostatečně velkými datovými typy (např. time_t).

Rychlé otevírání TCP spojení

Yuchung Cheng vytvořil nový mechanismus rychlého otevírání TCP spojení. Klasický postup třífázového handshakingu předpokládá, že data se posílají až po sestavení spoje, což hlavně na pomalých linkách výrazně prodlužuje latenci. RFC 793 s rychlým otevíráním počítá, ale do dokončení třífázového procesu se data nesmějí předávat aplikaci. Nový mechanismus odstraňuje většinu problémů spjatých s tím, že se data aplikaci předají hned. Implicitně by byl ale vypnutý, aplikace by o jeho použití žádaly speciálním příznakem ve volání sendto().

Proporcionální omezení rychlosti po ztrátě paketů

Současné řešení ztrát TCP paketů v Linuxu je sice lepší než to v RFC 3517 (namísto okamžitého zmenšení okna na polovinu se zmenšuje postupně po jednom paketu), ale není ideální. Nandita Dukkipati navrhla řešení, které začíná odhadem počtu paketů na cestě. Pokud je jich méně, než kolik by byla cílová velikost okna, zahájí se hned TCP slow-start s cílem obnovit hned původní velikost okna. Je-li dat více, postupuje se jako u současné implementace, ovšem počítá se relativně vůči novému oknu. Přesný algoritmus je popsán v draftu RFC.

Síťové fronty v uživatelském prostoru

Willem de Bruijn navrhl řešení (UNETQ) umožňující zpracovávat příchozí síťové pakety přímo v aplikaci, bez účasti jádra a zpracování v rámci softwarového přerušení. Koncept je založen na sdílení paměti (řešení zatím pracuje s využitím sysfs) mezi jádrem a aplikací, do této paměti by přicházely síťové pakety, které by se zpracovávaly v kontextu procesu, pro který jsou data určena.

Ovladače displejů: DRM versus framebuffer, přesun kódu do jádra

Čím dál více vývojářů se přiklání k tomu, aby se k zobrazování na displejích přistupovalo přes jediný mechanismus, a to DRM (a aby byl opuštěn framebuffer). V souvislosti s tím by se více zobrazovací logiky přesunulo do jádra. Zcela jednotný názor to ale není, asi nejvýznamnějším zástupcem odpůrců je Florian Tobias Schandinat, nový správce kódu framebufferu, který argumentuje stabilitou tohoto řešení a významnou uživatelskou základnou.

Rychlý vývoj

Přehled čerstvého dění okolo linuxového jádra ukazuje, že i přes dvacetiletou historii je Linux stále „velmi živým organismem“, který se rychle vyvíjí a proměňuje. Současně je vidět velká aktivita lidí pracujících na vývoji Linuxu, příval nových nápadů a ochota stále pracovat na dalším vylepšování. Ostatně stále nová zařízení, nové oblasti nasazení a nové přístupy k řešení určitých problémů přinášejí další a další výzvy, na které je potřeba reagovat.

Diskuze (5) Nahoru