ČTK (Česká tisková kancelář) upozorňuje (X), že na jejím zpravodajském webu České noviny byly dnes dopoledne neznámým útočníkem umístěny dva smyšlené texty, které nepocházejí z její produkce. Jde o text s titulkem „BIS zabránila pokusu o atentát na nově zvoleného slovenského prezidenta Petra Pelligriniho“ a o údajné mimořádné prohlášení ministra Lipavského k témuž. Tyto dezinformace byly útočníky zveřejněny i s příslušnými notifikacemi v mobilní aplikaci Českých novin. ČTK ve svém zpravodajském servisu žádnou informaci v tomto znění nevydala.
Byla založena nadace Open Home Foundation zastřešující více než 240 projektů, standardů, ovladačů a knihoven (Home Assistant, ESPHome, Zigpy, Piper, Improv Wi-Fi, Wyoming, …) pro otevřenou chytrou domácnost s důrazem na soukromí, možnost výběru a udržitelnost.
Společnost Meta otevírá svůj operační systém Meta Horizon OS pro headsety pro virtuální a rozšířenou realitu. Vedle Meta Quest se bude používat i v připravovaných headsetech od Asusu a Lenova.
Společnost Espressif (ESP8266, ESP32, …) získala většinový podíl ve společnosti M5Stack, čímž posiluje ekosystém AIoT.
Byla vydána nová stabilní verze 3.5 svobodného multiplatformního softwaru pro editování a nahrávání zvukových souborů Audacity (Wikipedie). Přehled novinek také na YouTube. Nově lze využívat cloud (audio.com). Ke stažení je oficiální AppImage. Zatím starší verze Audacity lze instalovat také z Flathubu a Snapcraftu.
50 let operačního systému CP/M, článek na webu Computer History Museum věnovaný operačnímu systému CP/M. Gary Kildall z Digital Research jej vytvořil v roce 1974.
Byl zveřejněn program a spuštěna registrace na letošní konferenci Prague PostgreSQL Developer Day, která se koná 4. a 5. června. Na programu jsou 4 workshopy a 8 přednášek na různá témata o PostgreSQL, od konfigurace a zálohování po využití pro AI a vector search. Stejně jako v předchozích letech se konference koná v prostorách FIT ČVUT v Praze.
Po 48 letech Zilog končí s výrobou 8bitového mikroprocesoru Zilog Z80 (Z84C00 Z80). Mikroprocesor byl uveden na trh v červenci 1976. Poslední objednávky jsou přijímány do 14. června [pdf].
Ještě letos vyjde Kingdom Come: Deliverance II (YouTube), pokračování počítačové hry Kingdom Come: Deliverance (Wikipedie, ProtonDB Gold).
Thunderbird 128, příští major verze naplánovaná na červenec, přijde s nativní podporou Exchange napsanou v Rustu.
Současné vývojové jádro je stále 2.6.31-rc5; od 31. července nebyly vydány žádné předverze. Patche dále proudí do hlavní řady (v době psaní tohoto článku 442 od 2.6.31-rc5) a vydání 2.6.31-rc6 lze očekávat každou chvíli.
-- Eric Sandeen
-- NeverSayDie, pořiďte si kopii ještě dnes.
Kdysi hlučná vývojová komunita Tux3 v posledních měsících poměrně ztichla. Dotaz na stav projektu vedl na jeden z citátů týdne z předchozích Jaderných novin, kde se vývojář Daniel Phillips přiznal k nedostatku času a vyjádřil lítost nad tím, že kód do hlavní řady nezačlenil již před měsíci. Když se jej Ted Ts'o ptal, čím je Tux3 zajímavý, odpověděl Daniel takto:
Co Tux3 potřebuje, je nějaká nová energie pro vývoj. Mohl by to být zajímavý projekt pro vývojáře, kteří chtějí začít s vývojem souborových systémů.
Mechanismus čítání zdrojů je zabudován do kontrolních skupin; je zamýšlen pro použití nástroji, jako je řadič spotřeby paměti. Tyto čítače uvnitř obsahují (to je překvapení) čítanou hodnotu, která sleduje aktuální využití zdroje danou kontrolní skupinou. Tento čítač narazil na stejný problém, na který naráží všechny často se měnící globální proměnné: Uboze škáluje kvůli poskakování řádku v cache mezi procesory. Využívání některých zdrojů (například stránek paměti) se může často měnit, což způsobí, že s tím spojený čítač bude systém jako celek brzdit.
Patch škálovatelných čítačů zdrojů, jehož autorem je Balbir Singh, má za cíl tuto situaci napravit. S tímto patchem se z jediného čítače „spotřeby“ stává pole čítačů pro každé CPU. Vzhledem k tomu, že každý procesor pracuje s vlastní kopií čítače, nedochází k poskakování řádku v cache a věci běží rychleji. Nevýhodou je, že součet je přibližný – čítače jednotlivých CPU jsou občas sečteny, aby se všechno udržovalo přibližně synchronní, ale udržování přesných hodnot by zlikvidovalo škálovatelnost, kterou má tento patch poskytnout. Dobrá zpráva je, že přesné součty stejně nejsou zapotřebí; dokud čítač obsahuje informaci, která je blízká realitě, bude systém fungovat v podstatě tak jako předtím – akorát trochu rychleji.
Bylo nebylo, spinlocky byly implementovány jako série inline funkcí s tím, že takto pro výkonnost kritické primitivum by mělo být tak rychlé, jak je to jenom možné. To se roku 2004 změnilo, když byly spinlocky změněny na normální funkce. Náklady spojené s voláním funkce trochu bolely, ale když spinlocky nebyly inline, jádro se významně zmenšilo, což je samo o sobě pro výkonnost výhodné. A tak spinlocky existují dodnes.
Kyvadlo se ale možná opět přehoupne na druhou stranu, minimálně pro architekturu S390. Heiko Carstens si všiml, že jsou volání funkcí na této architektuře poměrně drahá. Dal dohromady patch pro inline spinlocky a naměřil s ním 1-5% zlepšení výkonnosti. Rád by tedy patch vložil do hlavní řady společně s konfigurační volbou, která by každé architektuře umožňovala vybrat si nejlepší způsob, jak spinlocky implementovat. Doteď bylo k tomuto nápadu jenom málo názorů, ať už pro, nebo proti.
James Morris zaslal patch, který struktury seq_operations mění na konstantní v celém jádře. Tyto struktury jsou téměř vždy vyplněny při kompilaci a nikdy se nemusí měnit; umožnit přepis ukazatelů na funkce v nich se může hodit jenom těm, kdo chtějí jádro poškodit. Mnoho vnitřních operací VFS bylo během let nastaveno na const, ale seq_operations se doteď nikdo nevěnoval. James říká: Je to odvozeno od patche grsecurity, nicméně generováno od začátku, protože je to jednodušší, než změny separovat z něj.
Uprostřed diskuze o odolnosti vůči pádům a latenci souborového systému ext3 vystoupil Chris Mason s návrhem režimu data=guarded, který by zpozdil aktualizace metadat, když se mění velikost souboru, aby se zabránilo vyzrazení informací. Od té doby se patch data=guarded ztratil z dohledu. V reakci na dotaz Franse Popa Chris potvrdil, že na tomto kódu stále pracuje a že ho plánuje začlenit do 2.6.32.
Mezi těmi, kdo novinku uvítali, byl Andi Kleen, který poznamenal: data=writeback mě už při pádech stál pár souborů. Režim data=guarded nicméně s tímto konkrétním problémem pomoci nemusí: Ve skutečnosti je míněn jako způsob, jak sloučit bezpečnostní výhody data=ordered (konkrétně nevyzrazování náhodných dat) s výkonnostními výhodami data=writeback. Nejhorší problémy se ztrátou dat by měly již být vyřešeny opravami pro robustnost, které se do ext3 dostaly v 2.6.30.
Sledovací bod je značka ve zdrojovém kódu jádra, kterou – když je povolena – lze využít k zaháčkování do běžícího jádra v místě, kde je značka umístěna. Lze je použít mnoha nástroji pro ladění jádra a diagnostiku výkonnostních problémů. Jednou z výhod systému DTrace, který nalezneme v Solarisu, je rozsáhlá sada dobře zdokumentovaných sledovacích bodů v jádře (i jinde); umožňují správcům a vývojářům sledovat mnoho aspektů chování systému bez potřeby vědět toho hodně o jádře samotném. Linux naopak na večírek sledovacích bodů dorazil pozdě; hlavní řada jádra jich v současnosti obsahuje jenom hrstku. A jestli tento počet bude růst, to je stále v komunitě vývojářů diskutováno.
V Jaderných novinách jsme se na diskuzi o sledovacích bodech naposledy dívali v dubnu. Od té doby se debata vrátila bez velkých změn, v tomto případě ji spustil patch sledovacích bodů alokátoru stránek Mela Gormana, který více osazuje vrstvu správy paměti. Hlavní řada již obsahuje sledovací body pro volání funkcí jako kmalloc(), kmem_cache_alloc() a kfree(), Melův patch přidává sledovací body do nízkoúrovňového alokátoru stránek na místa jako free_pages_bulk(), __rmqueue_fallback() a __free_pages(). Tyto sledovací body poskytují náhled na to, jak se chová alokátor stránek; dostatečně poučeného uživatele informují o tom, že roste fragmentace nebo že se stránky stěhují mezi procesory. Přiložen je také skript pro pozdější zpracování, který používá data ze sledovacích bodů, a vytváří z nich seznam procesů, které v systému způsobují největší zátěž kódu správy paměti.
Jak se stalo již předtím, Andrew Morton zpochybnil hodnotu těchto sledovacích bodů. Stále nevidí potřebu pro tento druh nástroje, považuje ho spíš za ladící kód, který je obvykle užitečný jenom pro jediného vývojáře. Kromě toho se Andrew ptá, proč není možné relevantní informace přidat do /proc/vmstat, což je zavedené rozhraní pro poskytování informací o paměti do uživatelského prostoru.
Na tuto otázku je několik odpovědí. Jednou z nich je, že /proc/vmstat má mnoho omezení; nelze ho například použít pro monitorování specifické sady procesů – v podstatě obsahuje předvařené informace o správě paměti v systému jako celku. Pokud tedy vývojář potřebuje informaci, kterou tam nelze najít, takovou informaci bude v podstatě nemožné získat. Sledovací body naopak poskytují mnohem specifičtější informace, které lze filtrovat a tak získat preciznější pohled na systém. Mel nabídl jako ukázku skript pro SystemTap, který používá sledovací body k tomu, aby vytvořil seznam procesů, jež způsobují nejvíce alokací stránek.
Ingo Molnár zaslal dlouhý seznam příkladů toho, co by se se sledovacími body dalo udělat; některé z nich Mel později převzal a začlenil do dokumentu o jednoduchém používání sledovacích bodů. Tyto příklady si zaslouží pozornost; ukazují, jak rychle a jak daleko se vyvinulo osazení linuxového jádra (a s ním spojenými nástroji) sledovací infrastrukturou.
Jedním z klíčových tajemství pro rychlé využití sledovacích bodů je nástroj perf, který je s jádrem dodáván od 2.6.31-rc1. Tento nástroj byl napsán jako součást subsystému pro monitorování výkonnosti; lze ho například použít ke spuštění programu a monitorování počtu nenalezení dat v cache [cache miss] za jeho běhu. Jednou z vlastností, která se dostala do subsystému čítačů výkonnosti, je schopnost pracovat s událostmi sledovacích bodů jako s událostmi čítače výkonnosti. Je potřeba nastavit konfigurační volbu CONFIG_EVENT_PROFILE; poté může perf pracovat s událostmi sledovacích bodů úplně stejným způsobem, jakým obsluhuje události čítačů.
Když je konfigurace na místě a binárka perf je k dispozici, lze začít pohledem na to, které sledovací body jsou v systému k dispozici:
$ perf list … ext4:ext4_sync_fs [Tracepoint event] kmem:kmalloc [Tracepoint event] kmem:kmem_cache_alloc [Tracepoint event] kmem:kmalloc_node [Tracepoint event] kmem:kmem_cache_alloc_node [Tracepoint event] kmem:kfree [Tracepoint event] kmem:kmem_cache_free [Tracepoint event] ftrace:kmem_free [Tracepoint event] …
Kolik volání kmalloc() se v systému děje? Odpověď lze získat takto:
$ perf stat -a -e kmem:kmalloc sleep 10 Performance counter stats for 'sleep 10': 4119 kmem:kmalloc 10.001645968 seconds time elapsed
Takže na počítači autora článku, který byl v podstatě v klidu, se kmalloc() volalo téměř 420krát za sekundu. Volba -a dává výsledky pro celý systém, ale perf se také může dívat na specifický proces. Sledování alokací během překladu nástroje perf dává:
$ perf stat -e kmem:kmalloc make … Performance counter stats for 'make': 5554 kmem:kmalloc 2.999255416 seconds time elapsed
Více detailů lze získat záznamem dat a jejich následnou analýzou:
$ perf record -c 1 -e kmem:kmalloc make … $ perf report # Samples: 6689 # # Overhead Command Shared Object Symbol # …… ………… ……………………… ….. # 19.43% make /lib64/libc-2.10.1.so [.] __getdents64 12.32% sh /lib64/libc-2.10.1.so [.] __execve 10.29% gcc /lib64/libc-2.10.1.so [.] __execve 7.53% cc1 /lib64/libc-2.10.1.so [.] __GI___libc_open 5.02% cc1 /lib64/libc-2.10.1.so [.] __execve 4.41% sh /lib64/libc-2.10.1.so [.] __GI___libc_open 3.45% sh /lib64/libc-2.10.1.so [.] fork 3.27% sh /lib64/ld-2.10.1.so [.] __mmap 3.11% as /lib64/libc-2.10.1.so [.] __execve 2.92% make /lib64/libc-2.10.1.so [.] __GI___vfork 2.65% gcc /lib64/libc-2.10.1.so [.] __GI___vfork
Závěr: Největším zdrojem volání kmalloc() při jednoduchém procesu kompilace je getdents() volaný z make, následováno voláními execve() potřebnými ke spuštění překladače.
Nástroj perf může jít ještě dál; může například generovat grafy volání a disasemblovat kód kolem relevantních bodů specifických pro výkonnost. Více informací vizte v Ingově e-mailu a Melově dokumentu. I tak mluvíme pouze o statistikách sledovacích bodů; k dispozici je mnohem více informací, které lze následně zpracovávat skripty nebo nástroji jako SystemTap. Postačí říci, že sledovací body otevírají spoustu možností.
Jasná otázka je: Udělalo tohle všechno na Andrewa dojem? Zde je odpověď:
Naznačil, že by byl raději, kdyby nové sledovací body mohly být použity k odstranění /proc/vmstat a /proc/meminfo; tím způsobem by se nezvyšoval počet metod pro sledování správy paměti. Odstranění těchto souborů je ale z několika důvodů problematické – jedním z těchto důvodů je, že jsou součástí jaderného ABI, což se nemění snadno. Trvalo by několik let přeučit aplikace na jiné rozhraní a ujistit se, že již nezbývají žádní uživatelé souborů v /proc. Kromě toho jsou sledovací body dobré pro hlášení událostí, ale již méně vhodné pro hlášení současného stavu věcí. Sledovací body lze využít k pohledu na události alokace paměti, ale rozhraní jako /proc/vmstat je přímočařejší v případě, že chceme jenom vidět, kolik stránek je volných. Pro oba styly je tu tedy místo.
V době psaní tohoto článku nikdo nevydal konečné prohlášení o tom, jestli budou nové sledovací body začleněny. Andrew dal najevo, že i přes své obavy není zcela proti. Na lepší osazení jádra sledovací infrastrukturou je dostatečný tlak a s touto infrastrukturou lze dělat užitečné věci, takže jeden předpokládá, že se jí do hlavní řady postupem času dostane víc.
Jako součást změn pro podporu kontrolního bodu a restartu aplikací v jádře navrhl Sukadev Bhattiprolu nové systémové volání: clone_with_pids(). Když je proces, pro který byl vytvořen kontrolní bod, restartován, je pro některé aplikace důležité, aby měly stejné ID procesu (PID). Za normálních okolností jádro nově (pomocí clone()) spuštěné úloze přiřadí nepoužívané PID, ale pro procesy spuštěné od kontrolního bodu by to znamenalo, že se během jejich života změní jejich PID, což by mohl být nežádoucí vedlejší efekt. Sukadev hledá způsob, jak se tomu vyhnout tak, že lze při volání clone() specifikovat přitom PID potomka – nebo několik PID pro procesy ve vnořených jmenných prostorech.
Systémové volání je poměrně přímočaré. Přidává clone() parametr pid_set, který obsahuje seznam ID procesu; pid_set má zjevnou definici:
struct pid_set { int num_pids; pid_t *pids; };
Ukazatel na pid_set je funkcí clone_with_pids() předán jako poslední parametr. Každé PID se použije k určení toho, které PID má být přiřazeno na dané úrovni vnoření jmenného prostoru. Patch, který skutečně přidává clone_with_pids() (na rozdíl od dřívějších patchů v sadě, které připravovaly cestu), to ilustruje v příkladu (lehce pozměněného kvůli přehlednosti):
pid_t pids[] = { 0, 77, 99 }; struct pid_set pid_set; pid_set.num_pids = sizeof(pids) / sizeof(int); pid_set.pids = &pids; clone_with_pids(flags, stack, NULL, NULL, NULL, &pid_set);
Sada patchů předpokládá, že mít možnost nastavit PID je žádoucí, ale když byl tento přístup v březnu poprvé diskutován na linux-kernel, Linus Torvalds mu příliš nakloněn nebyl. Stěžoval si, že stavových atributů přiřazených k procesů je příliš mnoho, aby bylo vůbec kdy možné obecně zvládnout kontrolní body. Jeho návrh: Prostě naučte ten zatracený program, ve kterém chcete kontrolní body, že jeho pid se může změnit, a všem přiznejte, že ten, kdo potřebuje kontrolní body, na tom musí trochu zapracovat.
Jiní nesouhlasili – žádné překvapení – ale není jasné, jestli Linus změnil názor. Linus měl také obavy z bezpečnostních dopadů procesů, které budou moci požadovat přiřazení PID: Také to ale vypadá jako úžasný způsob útoku proti špatně napsanému softwaru v uživatelském prostoru, který posílá signály a má malé souběhy. Tuto obavu lze rozptýlit požadavkem, aby měl proces kvalifikaci CAP_SYS_ADMIN (v podstatě oprávnění roota), aby mohl clone_with_pids() používat.
Požadavek, aby restarty prováděl root, což prakticky znamená, že root bude muset mít pod kontrolou i proces vytvoření kontrolního bodu, obecně snižuje užitečnost kontrolního bodu/restartu. Je ale spousta problémů, které je potřeba vyřešit, než bude možné uživatelům povolit vytváření kontrolních bodů a obnovování ze svých vlastních obrazů, které klidně mohou být záměrně škodlivé. Nicméně, i když bude kontrolní body používat jenom root, je zde mnoho zajímavých aplikací.
Zbývá však ještě jeden zádrhel, na který Sukadev v patchi upozorňuje. V současnosti jsou všechny dostupné příznaky clone() alokovány. To clone_with_pids() neovlivňuje přímo, protože příznaky, které potřebuje, jsou již přítomné, ale při přidávání systémového volání je dobré dívat se do budoucnosti. Za tímto účelem jsou navrhovány dvě implementace systémového volání clone_extended(), které by bylo možné přidat místo clone_with_pids(), takže by se umožnilo přidat další příznaky clone() a zároveň podporovat restart.
První možností je změnit argument flags na ukazatel na pole záznamů o příznacích, se kterým by se pracovalo jako se sadou pro signal(), včetně operací pro nastavování, nulování a testování příznaků à la sigsetopts():
typedef struct { unsigned long flags[CLONE_FLAGS_WORDS]; } clone_flags_t; int clone_extended(clone_flags_t *flags, void *child_stack, int *unused, int *parent_tid, int *child_tid, struct pid_set *pid_set);
Podle návrhu by CLONE_FLAG_WORDS bylo na 64bitových architekturách nastaveno na 1, zatímco na 32bitových na 2, takže by se počet dostupných příznaků zdvojnásobil na 64. Pokud by bylo potřeba počet příznaků pro klonování zvýšit, podle potřeby by toto číslo šlo rozšířit, i když udělat to zpětně kompatibilním způsobem není zcela možné.
Další možností je věci rozdělit na dva parametry s tím, že současný příznak flags by se nechal být a přidal by se nový parametr clone_info, který obsahuje nové příznaky společně s pid_set:
struct clone_info { int num_clone_high_words; int *flags_high; struct pid_set pid_set; } int clone_extended(int flags_low, void *child_stack, void *unused, int *parent_tid, int *child_tid, struct clone_info *clone_info);
Podle Sukadeva mají oba přístupu výhody i nevýhody. První pro příznaky ve všech případech vyžaduje copy_from_user() (i když 64bitové architektury by se tomu prozatím mohly vyhnout), zatímco druhý sice vyžaduje podivné rozdělení příznaků, ale vyhýbá se copy_from_user() pro volání, která nepoužívají nové příznaky ani pid_set.
Je ale těžké si představit, že by kopírování kousku dat mělo měřitelný dopad na systémové volání, které vytváří proces, takže jako lepší volba se zdá být nějaká odvozenina z první možnosti. Také je těžké si představit, že bude zapotřebí více než 64 příznaků clone(), ale pokud by to opravdu bylo žádoucí, je potřeba nějaká cesta k poskytnutí kompatibility.
Proti implementaci clone_with_pids() nebyly žádné námitky, ale několik obecných komentářů se objevilo. Pavla Machka zajímala potřeba nastavovat PID všeho kromě nejvnitřnějšího jmenného prostoru; Serge E. Hallyn ale poznamenal, že vnořené jmenné prostory tuto schopnost potřebují: Mohli bychom restartovat aplikaci, která používá vnořený jmenný prostor, v takovém případě by restart specifikoval PID pro 2 (či více) nejvnitřnějších kontejnerů.
Pavel si také myslí, že by měl být soubor s dokumentací, který by nové systémové volání popisoval; Sukadev souhlasí, ale čeká na nějaký konsenzus ohledně clone_with_pids() či clone_extended() (a které z rozhraní se použije v tom druhém případě). Tento konkrétní aspekt zatím nikdo nekomentoval.
Toto je 4. verze sady patchů a historie ukazuje, že na dřívější komentáře bylo reagováno. Stále se jedná o fázi RFC nebo – jak to podává Sukadev – z větší části průzkumný patch, který má získat zpětnou vazbu ohledně rozhraní. Tato zpětná vazba se také ještě neobjevila, nicméně si lze položit otázku, jestli má Linus stále ještě námitky proti celému přístupu. Zdá se však, že existuje příliš mnoho důležitých aplikací kontrolních bodů a restartu – včetně migrace procesů a možnosti aktualizovat jádra s dlouho běžícími procesy – takže si nějaké řešení do jádra nakonec pravděpodobně cestu najde.
Síťové ovladače již nějaký čas používají čím dál tím hůře pojmenované rozhraní NAPI („nové API“). NAPI umožňuje síťovému ovladači vypnout přerušení od rozhraní a přejít do dotazovacího [polling] režimu. Dotazování je obecně považováno za špatnou věc, ale problém je to ve skutečnosti jenom v případě, když dotaz nezjistí žádnou užitečnou práci. U vytíženého síťového rozhraní vždy budou nějaké pakety, které je potřeba zpracovat, takže „dotazovat se“ v tomto případě znamená „pustit se do vyřízení nahromaděné práce“. A když je vždy nějaká práce, přerušení informující systém o tomto faktu jsou jenom šumem navíc. Jonathan Corbet, autor tohoto článku, rád takovou situaci přirovnává k upozornění na nový e-mail; každý, kdo dostává větší množství e-mailů, takové upozorňování pravděpodobně vypne. Ruší a když se dotyčný dostane k tomu, aby se podíval do pošty, pravděpodobně vždycky nějaký nový e-mail najde.
NAPI se pro síťové ovladače dobře hodí, protože velký počet paketů může vést k velkým počtům přerušení, ale tento přístup se nerozšířil do dalších částí jádra, kde jsou počty přerušení nižší. Tento stav se ve 2.6.32 může změnit, pokud Jens Axboe vytrvá ve svém plánu začlenit novou infrastrukturu blk-iopoll do hlavní řady. Ve zkratce je blk-iopoll NAPI pro bloková zařízení; část vnitřního kódu byla opravdu vypůjčena z implementace NAPI.
Konverze blokového ovladače na blk-iopoll je přímočará. Každé přerušující zařízení musí mít pro sebe definovanou strukturu struct blk_iopoll, pravděpodobně ve struktuře, která popisuje zařízení uvnitř ovladače. Tato struktura by měla být inicializována takto:
#include <linux/blk-iopoll.h> typedef int (blk_iopoll_fn)(struct blk_iopoll *, int); void blk_iopoll_init(struct blk_iopoll *iop, int weight, blk_iopoll_fn *poll_fn);
Hodnota weight popisuje relativní důležitost zařízení; vyšší hodnota znamená, že se v jednom dotazovacím cyklu zpracuje více požadavků. Jako u NAPI, ani zde není definitivní návod k tomu, jaká by hodnota weight měla být; v Jensově prvním patchi je nastavena na 32. Funkce poll_fn() se zavolá, když se blokový subsystém rozhodne, že je čas dotázat se na dokončené požadavky.
Dotazování na I/O pro zařízení řízeno voláními:
void blk_iopoll_enable(struct blk_iopoll *iop); void blk_iopoll_disable(struct blk_iopoll *iop);
blk_iopoll_enable() je potřeba zavolat předtím, než pro zařízení může dojít k nějakému dotazování. Povolení dotazování umožní, aby k němu docházelo, ale nevyvolá to – nemá cenu se dotazovat, když zařízení nedělá žádnou práci, takže bloková vrstva se zařízení nedotazuje, dokud ji ovladač neinformuje o tom, že by k tomu mohl být důvod.
To běžně nastane, když bude zařízení přerušovat. Ovladač může ve své obsluze přepnout na dotazovací režim procesem, který má tři kroky. První krok je kontrola globální proměnné blk_iopoll_enabled; pokud je nulová, dotazování nelze použít. Za předpokladu, že je dotazování povoleno, by měl ovladač připravit strukturu blk_iopoll voláním:
int blk_iopoll_sched_prep(struct blk_iopoll *iop);
V první verzi patche návratová hodnota nula znamenala, že příprava „selhala“, buď protože dotazování není povoleno, nebo protože zařízení již je v dotazovacím režimu. V budoucích verzích bude pravděpodobně smysl návratové hodnoty invertován ke standardnější variantě „nula znamená úspěch“. Když blk_iopoll_sched_prep() uspěje, ovladač může zavolat:
void blk_iopoll_sched(struct blk_iopoll *iop);
V tomto okamžiku se přejde do dotazovacího režimu; ovladač musí jenom zakázat přerušení od svého zařízení a vrátit se. Krok „zakázání přerušení“ by samozřejmě měl být proveden u zařízení samotného; maskování IRQ linky by bylo ve světě, kde se tyto linky sdílejí, antisociální.
Bloková vrstva později zavolá poll_fn(), která byla poskytnuta blk_iopoll_init(). Prototyp této funkce je:
typedef int (blk_iopoll_fn)(struct blk_iopoll *iop, int budget);
Dotazovací funkce je volána (v kontextu softwarového přerušení) s iop vztaženému ke struktuře blk_iopoll(), budget [rozpočet] je maximální počet požadavků, které by dotazovací funkce měla zpracovat. Při běžném používání lze strukturu specifickou pro zařízení ovladače získat podle iop pomocí container_of(). Hodnota budget je weight, která byla specifikována při inicializaci.
Návratová hodnota by měla být počet zpracovaných požadavků. Pokud zařízení spotřebuje méně, než je přidělený budget, mělo by dotazování vypnout voláním:
void blk_iopoll_complete(struct blk_iopoll *iopoll);
Přerušení od zařízení by měla být znovu povolena, protože k dalšímu dotazování již nedojde. Všimněte si, že bloková vrstva předpokládá, že ovladač nezavolá blk_iopoll_complete(), když celý svůj rozpočet spotřeboval. Pokud je nutné se vrátit k režimu přerušování přesto, že byl rozpočet vyčerpán, ovladač by měl buď (1) použít blk_iopoll_disable(), nebo (2) lhát ohledně počtu zpracovaných požadavků, když se vrací z dotazovací funkce.
Dalo by se uvažovat nad motivací této práce. Obsluha přerušení blokových zařízení většinou nebývá úzkým hrdlem výkonnosti. Problémem je zde rychlý vývoj úložných zařízení bez pohyblivých částí; očekává se, že zanedlouho budou tato zařízení pracovat v rozsahu stovek tisíc I/O operací za sekundu – což je mnohem více, než může zvládnout rotující úložiště. Když pracuje s tolika I/O operacemi, musí se jádro pečlivě snažit minimalizovat režii za požadavek jakýmkoliv způsobem. Jak si všimli jiní, bloková vrstva musí být podobnější síťové vrstvě, kde se cena za požadavek smršťuje na holé minimum. Kód blk-iopoll je krokem tímto směrem.
Jak velký je to krok? Jens zaslal nějaká předběžná čísla ukazující významné omezení spotřebovaného systémového času v benchmarku náhodného čtení z disku. Rozhodně bude potřeba další testování; konkrétně mají někteří vývojáři obavy z možnosti nárůstu latence I/O. První čísla ale naznačují, že tato práce vylepšila efektivitu blokové vrstvy při zátěži.
Nástroje: Tisk bez diskuse
Tiskni Sdílej:
kód na hlavní řady nezačlenil již před měsíciAsi spíš „do hlavní řady“…