Na čem aktuálně pracují vývojáři GNOME a KDE Plasma? Pravidelný přehled novinek v Týden v GNOME a Týden v KDE Plasma.
Před 25 lety zaplavil celý svět virus ILOVEYOU. Virus se šířil e-mailem, jenž nesl přílohu s názvem I Love You. Příjemci, zvědavému, kdo se do něj zamiloval, pak program spuštěný otevřením přílohy načetl z adresáře e-mailové adresy a na ně pak „milostný vzkaz“ poslal dál. Škody vznikaly jak zahlcením e-mailových serverů, tak i druhou činností viru, kterou bylo přemazání souborů uložených v napadeném počítači.
Byla vydána nová major verze 5.0.0 svobodného multiplatformního nástroje BleachBit (GitHub, Wikipedie) určeného především k efektivnímu čištění disku od nepotřebných souborů.
Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za duben (YouTube).
Provozovatel čínské sociální sítě TikTok dostal v Evropské unii pokutu 530 milionů eur (13,2 miliardy Kč) za nedostatky při ochraně osobních údajů. Ve svém oznámení to dnes uvedla irská Komise pro ochranu údajů (DPC), která jedná jménem EU. Zároveň TikToku nařídila, že pokud správu dat neuvede do šesti měsíců do souladu s požadavky, musí přestat posílat data o unijních uživatelích do Číny. TikTok uvedl, že se proti rozhodnutí odvolá.
Společnost JetBrains uvolnila Mellum, tj. svůj velký jazykový model (LLM) pro vývojáře, jako open source. Mellum podporuje programovací jazyky Java, Kotlin, Python, Go, PHP, C, C++, C#, JavaScript, TypeScript, CSS, HTML, Rust a Ruby.
Vývojáři Kali Linuxu upozorňují na nový klíč pro podepisování balíčků. K původnímu klíči ztratili přístup.
V březnu loňského roku přestal být Redis svobodný. Společnost Redis Labs jej přelicencovala z licence BSD na nesvobodné licence Redis Source Available License (RSALv2) a Server Side Public License (SSPLv1). Hned o pár dní později vznikly svobodné forky Redisu s názvy Valkey a Redict. Dnes bylo oznámeno, že Redis je opět svobodný. S nejnovější verzí 8 je k dispozici také pod licencí AGPLv3.
Oficiální ceny Raspberry Pi Compute Modulů 4 klesly o 5 dolarů (4 GB varianty), respektive o 10 dolarů (8 GB varianty).
Byla vydána beta verze openSUSE Leap 16. Ve výchozím nastavení s novým instalátorem Agama.
Začleňovací okno 2.6.32 je otevřené, není tedy žádná vývojová verze jádra. Byla začleněna obvyklá obrovská hromada patchů; shrnutí vizte v článku níže.
Současné stabilní jádro je 2.6.31; pro toto jádro nebyly vydány žádné stabilní aktualizace. Pro starší jádra bylo 15. září vydáno 2.6.27.34 a 2.6.30.7.
-- Mike Galbraith (díky Ingovi Molnárovi)
Na světě musí být spousta lidí, kteří si myslí, že by se mohli přidat k vývoji jádra, ale jenom pokud by to mohli udělat v Haskellu. Tady je webová stránka s instrukcemi, jak na to. Tím, že zajistíme, aby se GHC a překladový systém Linuxu setkaly na půl cesty, můžeme vytvořit moduly, které budou typově bezpečné a s garbage collectorem. S kopií GHC vytvořenou pro operační systém House jako základem se ukazuje, že je relativně jednoduché udělat potřebné změny nutné k vygenerování objektových souborů v prostředí jádra. To vede na kód jako tento:
hello = newCString "hello" >>= printk >> return 0
Jenom se to nepokoušejte začlenit do hlavní řady.
Arjan van de Ven ve svém weblogu představil nový nástroj nazvaný ,timechart‘ (časový plán). Timechart má za cíl zobrazit a diagnostikovat problémy s latencí na běžícím linuxovém systému. Aby to bylo možné řešit, pracuji na novém nástroji nazvaném Timechart založeném na ,perf‘, jehož cílem je na systémové úrovni ukázat, co se děje, při různé úrovni detailů. Ve skutečnosti je dokonce jedním z cílů, aby výstup bylo možné ,donekonečna přibližovat‘; tj. pokud budete chtít u něčeho vidět detaily, měli byste mít možnost se na ně podívat.
API Video4Linux2 je dobře vyvinuté rozhraní pro sdílení video bufferů mezi uživatelským prostorem a jádrem. Není však bezproblémové – jednoduchá video zachytávající zařízení přenášejí velké množství dat (video snímky), ale nedokáží používat I/O rozsyp/sesbírej [scatter/gather], což vynucuje alokaci velkých fyzicky spojitých bufferů. Řazení bufferů do fronty pro přenášení snímků může být významným zdrojem latencí, obzvláště pokud je nutné zamknout buffery v uživatelském prostoru v paměti nebo když architektura vyžaduje výrazné zneplatňování cache. Také by bylo hezké mít možnost předávat buffery přímo mezi video zařízením a zařízeními s ním spojenými, jako jsou například hardwarové kodeky, což ale současné API tak dobře nepodporuje.
V reakci na tyto problémy Laurent Pinchart navrhl nový subsystém implementující globální fond video bufferů. Tyto buffery by se alokovaly brzy při startu systému, což by obešlo nespolehlivost velkých spojitých alokací. Zneplatnění cache by bylo možné udělat předem, čímž by se odstranil významný zdroj latence při zachytávání. Explicitně je podporováno předávání bufferů mezi zařízeními. Návrh je v počátečním stádiu a Laurent by rád komentáře od vývojářů, kteří mají zájem.
V této fázi vývojového cyklu přirozeně přitahuje pozornost to, co bylo začleněno do hlavní řady. Může nicméně být zajímavé podívat se i na to, co se dovnitř nedostane. Tentokrát na opozici při začleňování narazilo několik věcí, které se kvůli tomu do jádra 2.6.32 dostat nemusí.
Jednou z nich je systémové volání reflink() (zmiňované minulý týden), kterému se od Linuse dostalo odpovědi „tohle přetahovat nebudu“. Mezi Linusovy námitky patří to, že systémové volání je zdánlivě skryto ve stromě ocfs2, obavy z toho, kolik bezpečnostních revizí a revizí ohledně VFS obdrželo, a nelíbilo se mu jméno. Raději by viděl jméno jako copyfile() a rád by, aby bylo flexibilnější; umožnit kopírování souborů na straně serveru na vzdálených souborových systémech byl jeden nápad, který se objevil.
V reakci na to Joel Becker navrhl nové systémové volání nazvané copyfile(), které má obsahovat více možností ohledně toho, jak se bude kopie provádět. Kromě Linuse nebylo k tomuto volání příliš komentářů, ale přinejmenším Linusovi se tento nový přístup líbí. reflink() se tedy pravděpodobně vyvine do copyfile(), ale zjevně není dostatek času na to, aby se tak stalo v začleňovacím okně 2.6.32.
Další kód, který naráží na problémy, je fanotify (popsáno v červenci). Problém je zde v tom, že se neobjevil skutečný konsenzus o tom, jak by toto API mělo vypadat. Současná implementace je založena na zvláštním socketu a několika volání setsockopt(), ale někteří tlačí na to, aby se místo toho použil netlink, zatímco jiní, aby byla vytvořena zvláštní sada systémových volání. Linus se do diskuze vložil později s tím, že by byl pro alternativu se systémovými voláními; také se zeptal:
To vedlo ke stále trvající diskuzi o tom, k čemu je fanotify, jestli je zapotřebí nové API pro upozorňování a jestli fanotify dokáže zvládat všechny věci, které by s ním lidé chtěli dělat. Významnou sadu možných problémů vizte v příspěvku Jamieho Lokiera. Vývojáři Linuxu zatím přidali dvě neadekvátní rozhraní pro upozorňování na soubory; je zde zájem na tom zajistit, aby to třetí bylo o něco lepší. Je tedy pravděpodobné, že fanotify si v tomto vývojovém cyklu posedí.
Linus začal přijímat patche pro začleňovací okno 2.6.32 10. září. Tím začíná proces, který by měl vést ke konečnému vydání jádra okolo začátku prosince. V době psaní tohoto článku bylo začlěněno nějakých 4400 neslučovacích sad změn. Nejvýznamnější změny viditelné pro uživatele zahrnují:
Byl začleněn patch vláken pro zpětný zápis vyhrazených pro BDI; to by mělo vést k lepší škálovatelnosti zpětného zápisu.
Byl začleněn virtuální souborový systém devfs. Tato vlastnost, která byla mnohými považována za návrat tolik neoblíbeného subsystému devfs, byla od počátku kontroverzní i přes fakt, že se od devfs významně liší a některé distribuce ji již s úspěchem využívají. Není tedy překvapující, že se proti začlenění objevila opozice. Linus ho nicméně v tichosti přijal, takže se objeví v 2.6.32.
Systémové volání keyctl() má nový příkaz (KEYCTL_SESSION_TO_PARENT), který zajistí, že svazek klíčů [keyring] volajícího procesu nahradí svazek klíčů jeho rodiče. Tato vlastnost je evidentně užitečná pro souborový systém AFS; také je zde nová sada háčků pro bezpečnostní moduly, které umožňují tuto funkci řídit.
Souborový systém sysfs nyní chápe bezpečnostní štítky [security labels], což umožňuje přísnější bezpečnostní politiku při přistupování k souborům v sysfs.
Architektura S390 nyní umí „volat domů“ a zaslat hlášení o jaderných oops na mateřskou loď servisní organizace. Tato funkce je řízena nezjevně pojmenovanou konfigurační volbou SCLP_ASYNC.
Kód OProfile nyní implementuje multiplexování čítačů výkonnosti, což umožňuje sběr širší kolekce statistik.
Byl přidán příznak SCHED_RESET_ON_FORK pro politiku plánovače. Tento příznak (popsaný v tomto článku) způsobí, že potomek od svého rodiče nezdědí zvýšenou prioritu nebo plánování v reálném čase.
Nástroj perf nyní obsahuje operaci trace; ta generuje jednoduchý výstupní proud z uživatelem specifikované sady sledovacích bodů.
Výchozí hodnota nastavení plánovače child_runs_first byla nastavena na „false“. To způsobí, že rodičovský proces běží po fork() dál místo toho, aby okamžitě předal procesor potomkovi. Více informací o změnách plánovače v 2.6.32 vizte v článku Různá témata ohledně plánovače níže.
Je zde nová sada sledovacích bodů plánovače, která zlepšuje viditelnost čekací doby wait, sleep a I/O wait. Sledovací body také přibyly pro nahrávání modulů a události čítání odkazů, vstup a výstup do/ze systémových volání, kopírování síťových paketů do uživatelského prostoru a události přerušení a paměťově mapovaného I/O v KVM.
V subsystému bezdrátového síťování byla odvedena spousta práce; většina z ní bylo pročišťování a vylepšování, které není přímo viditelné pro uživatele. Navíc byla vylepšena kompatibilita bezdrátových rozšíření a v cfg80211 je nyní podpora pro síťový jmenný prostor.
Architektura SPARC64 má nyní rudimentární podporu čítačů výkonnosti.
Do virtualizačního subsystému KVM přibyl modul nazvaný „irqfd“; ten hostiteli umožňuje vkládat do hosta přerušení. Společně s irqfd přichází nová vlastnost „ioeventfd“, která v hostitelích podporuje emulované paměťové I/O. KVM má nyní také podporu pro „neomezeného hosta“ podporovaného nejnovějšími procesory Intel s VMX.
V hlavní řadě je nyní mechanismus pro správu integrity TXT od Intelu
Nový modul pro „řízení VGA“ [VGA arbitration], který umožňuje nezávislým aplikacím správně fungovat s několika VGA zařízeními, která jsou připojena do stejného adresového prostoru. Řídí se pomocí /dev/vga_arbiter; detaily vizte v Documentation/vgaarbiter.txt.
Obvyklá hromada nových ovladačů:
Audio:
Desky a procesory:
Blokové:
Síťování:
Video4Linux: křemíkové řadiče Zarlink ZL10039
Různé:
Změny viditelné pro vývojáře jádra zahrnují:
Do struktury struct inode_operations byla přidána nová operace check_acl(). To je součástí Linusova tlaku na to, aby se logika testování práv přesunula do jádra VFS a přitom se omezilo zamykání.
V API bezpečnostních modulů je nový háček kernel_module_request(); umožňuje bezpečnostním modulům rozhodnout, jestli volání request_module() smí uspět. Také přibyla nová sada háčků pro ovladač TUN.
Pro architektury, kde se tak budou chovat lépe, lze spinlocky přeložit jako inline funkce.
Implementace „klasické čtení-kopie-zápis“ [read-copy-update] a „preempt RCU“ byly odstraněny ve prospěch „stromového RCU“ a „bloatwatch RCU“.
Kód pro nízkoúrovňovou obsluhu přerušení získal podporu pro řadiče přerušení, ke kterým se přistupuje přes pomalé sběrnice (řekněme I2C). Mezi jinými věcmi to vede k přidání příznaku IRQF_ONESHOT, který způsobí, že přerušení s obsluhou ve vlákně zůstane v době mezi spuštěním tvrdé [hard] obsluhy a obsluhy ve vlákně maskované.
Sledovací kruhový buffer je nyní zcela bezzámkový na straně zapisovatele. Detaily vizte v článku Bezzámkový kruhový buffer.
Jak bylo krátce popsáno v článku Nadcházející změna síťového API, změnilo se síťové API. Typ návratové hodnoty pro ndo_start_xmit() je nyní enum netdev_tx_t. Pro většinu ovladačů bude postačovat změna deklarované návratové hodnoty.
Kód pro omezení přerušení blokové vrstvy blk-iopoll byl začleněn.
Konfigurace jádra pomocí make localmodconfig vytvoří konfiguraci omezenou na moduly, které jsou v současnosti nahrány v běžícím jádře. make localyesconfig tyto moduly vloží přímo do jádra.
Bylo začleněno nové jádro správy napájení.
Začleňovací okno by mělo zůstat otevřeno alespoň jeden další týden; není jasné, jak tento plán ovlivní LinuxCon a Linux Plumbers Conference. Příští vydání bude obsahovat nové informace o změnách, ke kterým došlo po uvedení tohoto článku.
Vývoj spojený s plánovačem, zdá se, přichází v dávkách. Během několika vývojových cyklů je relativní ticho a najednou aktivita vzroste. Nyní se pravděpodobně nacházíme v období, kdy vývojáři začínají vykazovat vyšší zájem o to, co plánovač dělá. Zaslání plánovače BFS rozhodně část této aktivity motivovalo, ale děje se toho víc.
Na frontě BFS (mírně) hořlavá část diskuze, zdá se, skončila. Každý, kdo sleduje konferenci linux-kernel, ví, že po bouři většinou následují vážně míněné pokusy opravit problémy; a tak je tomu i tentokrát. Mnoho lidí zasílá benchmarky; obecné pravidlo je, že výsledky těchto benchmarků bývají smíšené. Také jsou zde vývojáři a uživatelé, kteří zasílají příspěvky o problémech, které pozorují; vizte například hlášení, které poslal Jens Axboe o desetivteřinové pauze, když se pokusil spustit příkaz xmodmap.
Jako součást procesu vyhledávání problémů se konverzace stočila k ladění plánovače. Ingo Molnár poukázal na to, že je celá sada příznaků určujících chování plánovače, a všechny z nich může správce systému ladit:
Hlavní myšlenkou zde není to, že by si uživatel měl vybrat správný plánovač z 32768 – což je číslo, které je poněkud vysoké i pro lidi, co tvrdí, že „Linux je o možnosti volby“. Tyto příznaky ale mohou být užitečné pro každého, kdo se pokouší zjistit, proč není chování plánovače tak dobré, jak by mohlo být. Když ladění nastavení věci zlepší, dává to vývojáři nápovědu k tomu, kde má hledat zdroj problému.
Konkrétní test, který navrhl Ingo, byl tento:
echo NO_NEW_FAIR_SLEEPERS > /debug/sched_features
(Politicky korektní vývojáři budou mít samozřejmě debugfs připojený pod /sys/kernel/debug. Autor článku nezaujímá žádný postoj ohledně správného přípojného bodu debugfs.)
Jeden z testovatelů okamžitě hlásil, že nastavení tohoto příznaku hned způsobilo, že problémy zmizely. Jens také oznámil, že jeho problém s desetivteřinovým xmodmap je vyřešen. Důkazy o problémech s vlastností NEW_FAIR_SLEEPERS byly tak přesvědčivé, že Ingo zaslal patch, který ji ve výchozím nastavení zakazuje; tento patch byl začleněn do 2.6.32.
Pro toho, kdo má zájem o podrobnější informace, NEW_FAIR_SLEEPERS je jednoduchá vlastnost, která dává procesu malé zvýhodnění, pokud se vrátí do fronty mezi běžící po spánku. Má pomoci interaktivním procesům, ale něco zjevně nefunguje tak, jak se očekávalo. Jakmile bude skutečný problém nalezen, je možné, že NEW_FAIR_SLEEPERS bude opět ve výchozím nastavení povoleno. Do té doby mohou uživatelé, kteří mají problémy s interaktivitou, zkusit tuto vlastnost zakázat a zjistit, jestli se stav nezlepší.
Další parametr, jehož výchozí hodnota se v 2.6.32 mění; určuje, který proces po fork() běží první. Již nějakou dobu fork() nastavuje věci tak, že potomek chvíli běží předtím, než se běh programu vrátí z funkce fork() u rodiče; toto chování je založeno na obecném pozorování, že práce potomka je často důležitější. Je nicméně dobrý důvod, aby rodič běžel první: Stav rodiče je v procesoru aktivní, TLB obsahuje správné informace atd. Varianta „první běží rodič“ by se tedy měla chovat lépe. Zdá se, že výkonnost přístupu rodič běží první překonává přístup potomek běží první na nejdůležitějším benchmarku ze všech: Na překladu jádra. To bylo dostatečné k tomu, aby se výchozí hodnota změnila.
Objevily se obavy, že by tato změna mohla odhalit nějaké chyby v aplikacích. Jesper Juhl tyto obavy vyjádřil takto:
„Potomek běží první“ ale nikdy nebylo součástí API fork(); není to nic, na co by se aplikace měly spolehnout. I před změnou se chování mohlo lišit vlivem preempce, na SMP systému a kvůli dalším vlivům. Skutečná pravda tedy je, že nikdy nebylo garantováno, že potomek poběží první. To uživatelům ale nijak nepomůže, pokud jim přestanou fungovat aplikace; aby jim bylo pomoci, v sysctl je nový ladící prvek kernel.sched_child_runs_first; pokud je nastaven na 1, obnoví se původní chování.
Plánování aktivního CPU je zajímavé, ale pracuje se i na jiné oblasti: Co se stane, když nikdo CPU nechce? Současné procesory obsahují mnoho vlastností pro správu napájení, které lze použít k omezení spotřeby, když se nic neděje. Je zjevné, že každý, kdo se zajímá o spotřebu energie, bude chtít, aby byl procesor ve stavu nízké spotřeby, kdykoliv je to možné. S politikou „přepni do režimu nízké spotřeby, když je klid“, jsou ale problémy:
Přechody mezi stavy samy o sobě spotřebovávají energii. Pokud je CPU přepnuto do stavu velmi nízké spotřeby, aby bylo o pár mikrosekund později znovu aktivováno, celková spotřeba energie se zvýší.
Přechody mezi stavy mají dopad na výkonnost. Extrémním příkladem by mohlo být jednoduché vytažení zástrčky; spotřeba energie bude úžasně nízká, ale systém bude mít tak ubohou odezvu, že to nespraví ani plánovač BFS. Přepnutí CPU do více konvenčního stavu nízké spotřeby stále bude vytvářet latence; chvíli trvá, než se procesor vrátí do pracovního režimu. Příliš rychlý přechod do stavu nízké spotřeby tedy výkonnost systému ovlivní negativně.
Ukazuje se, že kód CPU governoru v hlavní řadě se v tomto ohledu často rozhodne špatně, obzvláště na nových procesorech Intel Nehalem; výsledkem je plýtvání energií a ubohá výkonnost, kde „ubohá výkonnost“ znamená postih téměř 50 % v některých z testů, které zkoušel Arjan van de Ven. Ten dal dohromady patch, který má problémy opravit. Použitý přístup je zajímavý.
Zjevně nemá smysl přepnout procesor do režimu nízké spotřeby, když bude ve velmi blízké budoucnosti znovu plně vytížen. Všechno, co tedy kód governoru musí udělat, je přijít s přesvědčivou předpovědí budoucnosti, aby věděl, kdy bude CPU znovu potřeba. Bohužel producenti čipů zase odložili začátek prodeje tak dlouho slibovaných křišťálových koulí, takže se kód musí spoléhat na heuristiku; software tedy opět musí dohánět nedostatky hardwaru.
Když je potřeba uhádnout, kdy by se CPU mohlo probudit, je potřeba zvážit dvě věci. Jedna je známa velmi dobře: Čas příští naplánované události časovače. Časovač v tomto případě určuje horní hranici toho, jak dlouho CPU může spát, ale to není definitivní hodnota; CPU mohou probudit přerušení předtím, než vyprší časovač. Arjanův governor se pokouší uhodnout, kdy by mohlo dojít k přerušení, podle předchozího chování systému. Pokaždé, když se procesor probudí, kód governoru vypočítá rozdíl mezi odhadnutou hodnotou a skutečným časem nečinnosti. Uchovává se klouzavý průměr této hodnoty a z něj se přesněji (snad) odhaduje čas nečinnosti.
Ve skutečnosti se uchovává několik klouzavých průměrů. Pravděpodobnost, že bude velmi dlouhá doba nečinnosti ukončena přerušením, je vyšší, než že k přerušení dojde při krátké nečinnosti. Uchovává se tedy korektivní hodnota [correction factor] pro každý řád doby nečinnosti – odhad 1 ms bude mít jinou korektivní hodnotu než odhady 100 μs a 10 ms. Krom toho se používá (a uchovává) úplně jiná sada korektivních hodnot pro situace, kdy na současném CPU probíhá I/O – pokud procesy čekají na krátkodobé (blokové) I/O, je šance na předčasné probuzení vyšší.
Obava o výkonnost je řešena pokusem přijít s nějakým odhadem toho, jak špatně by latence způsobená změnami stavů napájení poškodila systém. U CPU, které nemá moc práce, pravděpodobně nebude problém, když se na chvíli uspí. Pokud je naopak vytížené, bude pravděpodobně lepší, když zůstane zapnuté a připravené k práci. „Zaneprázdněnost“ se kód governoru pokouší kvantifikovat výpočtem „násobitele“ [multiplier]:
násobitel = 1 + 20*load_average + 10*iowait_count
Všechna čísla jsou specifická pro aktuální CPU; násobitel je výrazně ovlivněn průměrným zatížením systému a o něco méně počtem procesů, které čekají na I/O. Nebo tak se to alespoň zdá – mějte na paměti, že nepřerušitelně čekající procesy (jako jsou procesy čekající na blokové I/O) se započítávají do průměrného vytížení, takže jejich vliv je vyšší, než by se mohlo zdát. Ve shrnutí násobitel roste s tím, jak roste počet aktivních procesů.
Konečným krokem je zjištění všech dostupných stavů snížené spotřeby, které procesor nabízí, nejhlubším spánkem počínaje. Každý stav má přiřazenu hodnotu „latence opuštění“ [exit latency], která popisuje, jak dlouho trvá se z tohoto stavu dostat; hlubší spánek má větší hodnotu latence opuštění tohoto stavu. Nový kód governoru násobí hodnotu latence opuštění násobitelem vypočítaným výše, pak výsledek porovná s nejlepším odhadem času nečinnosti. Pokud doba nečinnosti překročí upravenou hodnotu latence pro daný stav, je tento stav použit. Vzhledem k tomu, že se zapojují vysoké násobitele, je vidět, že očekávaná doba nečinnosti musí být poměrně rychle poměrně dlouhá, když zátěž systému roste.
Podle Arjana tato změna vrací výkonnost někam velmi blízko k systému, který úsporné režimy vůbec nepoužívá. Zlepšení je tak významné, že by Arjan rád začlenil tento kód do 2.6.32, i když se objevil až v začleňovacím okně. K tomu může dojít, i když je možné, že se z tohoto kódu pro jeden vývojový cyklus stane samostatný CPU governor pro případ, že by se objevily regrese.
Originál tohoto článku pro LWN.net napsal Jon Ashburn.
Moderní procesory podporují funkce hardwarového bodu přerušení [breakpoint] či sledovacího bodu [watchpoint], ale linuxové jádro ladícím nástrojům, jako jsou kgdb a gdb, neposkytuje způsob, kterým by bylo možné k těmto registrům přistupovat s tím, že jsou s někým sdílené. Současné ladění několika procesů tedy může snadno kolidovat se současným použitím těchto registrů, takže se debugger začne chovat podivným a matoucím způsobem – když například program pokračuje v běhu přes bod přerušení, je to pro programátora rozhodně matoucí.
Problém je řešen pomocí navrhovaného jaderného API nazvaného hw-breakpoint (nebo alternativně hw_breakpoint). Tato funkčnost vyvinutá v sérii patchů, jejichž autory jsou K. Prasad, Frederic Weisbecker a Alan Stern, si klade za cíl poskytnout konzistentní, přenositelnou a robustní metodu, kterou by několik programů mohlo použít k přístupu ke speciálním ladícím hardwarovým registrům. Tyto registry jsou užitečné pro kteroukoliv aplikaci, která potřebuje pozorovat přístupy k paměti nebo na základě přístupu spustit shromáždění informací o programu. Takové aplikace zahrnují ladění, sledování a monitoring výkonu. I když se tyto patche původně zaměřují na x86, snaží se poskytnout obecné API, které je možné podporovat způsobem nezávislým na architektuře na různých procesorech. I když se ještě dolaďují detaily, s hw-breakpoint lze ladící prostředky používat současně několika uživateli přenositelnějším způsobem.
Nejčastější případy ladění, které by mohly použít patche hw-breakpoint, jsou situace narušení paměti. Chyby v programu, jako je například chybný ukazatel, přetečení bufferu a chybné alokace/dealokace paměti, mohou vést k narušení paměti, kde jsou platná data omylem přepsána. Tyto chyby je obtížné najít; narušení může nastat kdekoliv v programu a chyba vyplývající z poškození dat se často projeví dlouho poté, co k narušení došlo. Nelze je většinou vypátrat zaměřením se na lokální části kódu, který explicitně přistupuje k poškozeným datům. Pro ladění problémů s narušením paměti se jako první volba používají sledovací body, což je speciální typ bodu přerušení.
Přerušovací body zastaví vykonávání programu na zadané dané adrese a předají řízení debuggeru. To umožňuje prozkoumat stav programu (proměnné, paměť a registry). Když programátoři mluví o bodu přerušení, obvykle mají na mysli softwarové body přerušení – například příkaz break v gdb nastaví softwarové přerušení na specifické adrese instrukce. Tato instrukce je nahrazena pastí [trap instruction], jejíž vykonání předá řízení gdb.
V kontrastu s tím jsou sledovací body nejlépe implementovány pomocí hardwarových sledovacích bodů; softwarová implementace sledovacích bodů je extrémně pomalá. Hardwarové sledovací body nicméně vyžadují zvláštní ladící registry v procesoru; tyto registry zajišťují nepřetržité porovnávání adres generovaných procesorem a když se adresa v registru shoduje s vygenerovanou adresou, je spuštěna obsluha.
K paměti se může přistupovat kvůli čtení dat, zápisu dat nebo vykonání instrukce [fetch], takže hardwarové body přerušení obvykle podporují zastavení nejenom podle adresy, ale také podle typu přístupu: čtení, zápis, čtení/zápis a vykonání. Hardwarové ladící registry mohou kromě zastavení při přístupu do paměti podporovat také reakci na přístup na I/O porty. V každém případě sledovací bod zachycuje přístup k datům jakéhokoliv typu, ne pouze přístup k instrukci, která má být vykonána. Vzhledem k tomu, že k narušení paměti může dojít kdekoliv v programu, sledovací bod zachycující zápisy do poškozené proměnné/poškozeného místa může být velmi dobrým prostředkem, kterým lze takové chyby chytit při činu.
Tyto hardwarové ladící registry jsou omezeným zdrojem: Procesory Intel x86 podporují maximálně čtyři hardwarové přerušovací body/sledovací body použitím registrů pro zvláštní účely DR0 – DR7. Do registrů DR0 až DR3 lze naprogramovat adresy požadovaných přerušovacích bodů/sledovacích bodů ve virtuální paměti. DR4 a DR5 jsou rezervovány pro využití procesorem, DR6 je stavový registr, který poskytuje informace o tom, na který přerušovací bod se naposledy narazilo a DR7 je registr, který přerušovací body řídí – ovládá například lokální/globální povolování, typ přístupu k paměti a délku přístupu k paměti. Jako u všech omezených hardwarových prostředků musí i zde musí několik současně běžících programů o tyto registry soupeřit.
Vzhledem k tomu, že existující vydaná jádra nijak neřídí ani nespravují přístup k těmto registrům, jejich softwaroví uživatelé se mohou při jejich používání střetnout, aniž by o tom věděli. Hw-breakpoint tento problém řeší tím, že rozhoduje o přístupu k těmto omezeným hardwarovým registrům jak z uživatelského prostoru, tak z jádra. Procesy v uživatelském prostoru, jako je například gdb, k nim přistupují pomocí systémového volání ptrace. Přístupy z prostoru jádra zahrnují kgdb a KVM (pouze při přepínání kontextu mezi hostitelem a hostem). Řízení hw-breakpoint brání tomu, aby si debuggery v jádře a/nebo v uživatelském prostoru vzájemně šlapaly na nohy.
Byly vyvinuty další patche, které API hw-breakpoint využívají. Byl vyvinut plug-in pro ftrace (ftrace bylo v JN diskutováno v článcích Pohled na ftrace a Dynamické sondy s ftrace), který umožňuje dynamicky sledovat kterýkoliv jaderný globální symbol. Tato funkce nazvaná ksym_tracer umožňuje zobrazovat přes debugfs všechny přístupy k jaderné proměnné pro čtení i zápis. Vzhledem k tomu, že používá API hw-breakpoint, spoléhá se na hardwarovou podporu bodů přerušení pod sebou. Tato nová vlastnost ftrace by mohla být velmi užitečná pro chyby narušení paměti, které je obtížné zachytit sledovacími body. Mezi takové problémy patří věci jako 1) chybný zápis, který se schovává mezi velkým počtem korektních zápisů, 2) nutnost nastavit na vzdáleném stroji spuštění Kdbg a 3) jaderné chyby, které se neprojevují, když je stroj zastaven přerušovacím bodem. Hw-breakpoint umožňuje současné používání ksym_tracer a sledovacích bodů debuggeru bez rizika poškození ladícího registru.
Kromě ftrace lze pomocí obecného hw-breakpoint vylepšit i čítače výkonnosti (vizte články Čítače výkonnosti a Čítače výkonnosti přidány do hlavní řady) – specificky lze čítače aktualizovat podle přístupu k datům místo podle vykonávání instrukcí. Byl vyvinut patch, který používá hardwarové přerušovací body v jaderném prostoru ke sledování výkonnosti událostí spojených s přístupem k datům. Například lze čítat přístupy ke spinlocku sledováním samotného příznaku spinlocku. V současnosti je tento patch poněkud omezen, co se podpory definice a využití čítačů přerušovacích bodů týče. Plánují se však další vlastnosti.
Vzhledem k začlenění patchů ftrace a čítačů výkonnosti lze nyní API hw-breakpoint potenciálně využít několika kousky kódu: kgdb, KVM, ptrace a čítači výkonnosti. Tento potenciál pro vyšší využívání zvýšil i zkoumání API různými vývojáři: hw-breakpoint již není starost jenom pro vývojáře ladění. Toto větší zkoumání vedlo k významným změnám v kódu hw-breakponit, které stále probíhají. Konkrétně spojení hw-breakpoint a čítačů výkonnosti vedlo k tomu, že byla velká část původní struktury a funkčnosti hw-breakpoint přepracována.
Původní podporu funkčnosti hw-breakpoint (před čítači výkonnosti) vyvíjel hlavně K. Prasad. Podporovala globální, celosystémové přerušovací body v jaderném prostoru a přerušovací body pro jednotlivá vlákna v uživatelském prostoru. Zatímco přerušovací body v uživatelském prostoru byly povoleny pouze během vykonávání vlákna, jaderné přerušovací body byly vždy přítomny na všech CPU v systému. Navíc nebyla implementována žádná politika pro rezervace, požadavky na hardwarové ladící registry byly vyřizovány na základě politiky kdo dřív přijde, ten dřív mele. Když se používaly všechny fyzické ladící registry, hw-breakpoint vracel při dalších požadavcích na přerušovací bod chybu.
Jak poznamenal Peter Zijlstra, původní implementace hw-breakpoint je pro podporu čítačů výkonnosti naprosto nevyhovující ze tří důvodů:
Prvním důvodem je to, že čítače (jak v jaderném, tak v uživatelském prostoru) lze definovat pro procesor nebo pro úlohu; to je v konfliktu s celosystémovými jadernými přerušovacími body hw-breakpoint.
Za druhé jsou čítače pro jednotlivé úlohy čítači výkonnosti plánovány tak, aby se ušetřilo nepotřebné přepínání kontextu hardwarových prostředků pod nimi, když to není nutné.
A za třetí čítače výkonnosti lze multiplexovat jejich přidělováním v časových úsecích i nad hranici počtu hardwarových PMU (performace monitoring unit, jednotka pro sledování), přičemž tato hranice je pro body přerušení 4.
Tato rozdílnost čítačů výkonnosti a hw-breakpoint vedla k debatě o tom, jestli je nějaké propojení mezi nimi vůbec možné. Nicméně se došlo ke konsenzu, že zaintegrování hw-breakpoint do infrastruktury rezervace a plánování PMU čítačů výkonnosti by bylo užitečné vzhledem k bohatší podpoře čítačů výkonnosti pro plánování, rezervace a správu hardwarových prostředků. O těchto výhodách Frederic Weisbecker píše:
Patch nově zaslaný v tomto týdnu je Fredericův kód pro integraci hw-breakpoint a čítačů výkonnosti. Koncepčně dělí funkčnost hw-breakpoint na dvě poloviny: 1) API na horní úrovni a 2) nízkoúrovňové řízení ladících registrů. Mezi těmito polovinami leží funkčnost čítačů výkonnosti. S tímto patchem je každý bod přerušení specifická instance čítače výkonnosti nazvaná čítač bodu přerušení. Čítač výkonnosti řeší plánování registrů a propojení těchto instancí čítače bodu přerušení mezi vláknem a CPU. Modifikované API hw-breakpoint stále obsluhuje požadavky od ptrace(), ftrace a kgdb tím, že vytvoří čítač bodu přerušení. Tento čítač lze také vytvořit přímo existujícím systémovým voláním (perf_counter_open()). Vrstva čítače bodu přerušení komunikuje s nízkoúrovňovým a pro architekturu specifickým kódem hw-breakpoint, který se stará o čtení a zápis ladících registrů procesoru.
Bohužel kvůli této nedávné integraci do čítačů výkonnosti se API hw-breakpoint změnilo a plánují se další změny. Místo detailního rozboru celého API, které se pravděpodobně bude měnit, tedy následuje jenom jeho shrnutí. Pro nastavení nového hardwarového bodu přerušení jsou poskytnuty dvě funkce:
int register_user_hw_breakpoint(struct task_struct *tsk, struct hw_breakpoint *bp); int register_kernel_hw_breakpoint(struct hw_breakpoint *bp, int cpu);
kde:
cpu je číslo cpu, na kterém má být breakpoint nastaven; *tsk je ukazatel na 'task_struct' procesu, kterému patří adresa; *bp je ukazatel na informace o bodu přerušení, mezi které patří: 1) ukazatel na obslužnou funkci, která má být zavolána, když se narazí na bod přerušení 2) ukazatel na data specifická pro architekturu (struct arch_hw_breakpoint).
struct arch_hw_breakpoint obsahuje vlastnosti bodu přerušení, jako je adresa bodu přerušení v paměti, typ přístupu do paměti (čtení/zápis, čtení nebo zápis) a délka přístupu do paměti (byte, short, word, …). Tyto parametry velmi závisí na specifické podpoře poskytované hardwarem – například zatímco x86 podporuje adresy ve virtuální paměti, jiné procesory podporuje adresy ve fyzické paměti. Vzhledem k tomu, že API má za cíl být nezávislé na architektuře, je na architektuře závislá tato struktura.
Aby nebylo nutné registrovat a odregistrovat bod přerušení, pokud je ho jenom potřeba změnit, je poskytována následující funkce:
int modify_user_hw_breakpoint(struct task_struct *tsk, struct hw_breakpoint *bp)
Hardwarový bod přerušení je odstraněn deregistrující funkcí:
void unregister_hw_breakpoint(struct hw_breakpoint *bp)
Hw-breakpoint se snadno dostal do stromu -tip, stromu vývojových zdrojových kódů jádra, který spravuje Ingo Molnár. V červnu bylo předběžně plánováno začlenění z -tip do 2.6.32, zpožděná integrace do čítačů výkonnosti nicméně jakékoliv začlenění přesouvá za 2.6.32.
Ať už bude vydáno kdykoliv, API hw-breakpoint slibuje poskytnout přenositelnou a robustní metodu, pomocí které mohou debuggery přistupovat k hardwarovým bodům přerušení bez konfliktu. I když byla jeho funkčnost původně relativně izolovaná vlastnost pro podporu debuggerů, vznikly z něj nové vlastnosti pro sledování a monitorování výkonnosti. Tyto nové vlastnosti by se mohly ukázat jako užitečné v situacích, kdy správnou spouští pro sběr dynamických informací není přístup k instrukci, ale přístup k datům. Díky využití funkčnosti plánování a rezervace zdrojů v čítačích výkonnosti má hw-breakpoint velmi zobecněnou metodu pro správu omezeného počtu registrů hardwarových bodů přerušení. Vydání hw-breakpoint přináší příslib, že uživatelům Linuxu zpřístupní nové způsoby, kterými vysledovat problematické chyby jako narušení paměti, a že dovolí, aby dynamické techniky pro přístup k datům (jako jsou sledovací body gdb a sledovač ksym_tracer v ftrace) dobře fungovaly společně.
Nástroje: Tisk bez diskuse
Tiskni
Sdílej:
Velmi zajímavé čtení! Díky za skvělý překlad.
cowloop
je o úroveň níž - atímco aufs
je na úrovni VFS a pracuje se soubory, cowloop
je na úrovni blokového zařízení a pracuje tudíž na úrovni bloků. Implementace je taková, že je k příslušnému blokovému zařízení přiřazen soubor, pokud možno řídký (sparse), ve kterém je na začátku bitmapa bloků (je v souboru/není v souboru) a potom samotné bloky.
Pokud dojde k pokusu o čtení, cowloop
koukne do bitmapy a pokud tam blok je, čte ho ze souboru, v opačném případě ho čte ze zařízení. Při zápisu se blok zapíše do soboru a v bitmapě se nastaví jako platný.
Takže zatímco aufs
je výhodné pro soborové systémy, které jsou přirozeně read-only (squasfhs
, cramfs
, iso9600
...), je cowloop
pro běžné read-write souborové systémy, které ovšem dlí na read-only médiu, nebo na médiu, do kterého není moc dobré často zapisovat (flash karty a pod.). Něco podobného umí i LVM, ale tam je celkem netriviální syntaxe a místo pro zapisované bloky musí být také zařízení, zatímco u cowloop
stačí soubor.
echo NO_NEW_FAIR_SLEEPERS > /sys/kernel/debug/sched_featuresmi opravdu spravilo interaktivitu, už žádný trhaný zvuk ani při
powersave
! Ta fíčura je opravdu rozbitá.