GNU/Linux >> Znalost Linux >  >> Linux

Linux – Proč byly v roce 2013 hlášeny problémy se zastavením USB? Proč nebyl tento problém vyřešen stávajícím kódem „no-i/o špinavého omezení“?

Zhoubný problém se zastavením USB flash disku – LWN.net, listopad 2013.

Artem S. Tashkinov nedávno narazil na problém, který bude alespoň některým čtenářům LWN známý. Zapojte pomalé úložné zařízení (řekněme USB flash disk nebo přehrávač médií) do počítače se systémem Linux a zapište na něj spoustu dat. Celý systém se zablokuje , možná několik minut.

Tentokrát však Artem učinil zajímavý postřeh:systém se zablokoval, pokud by běžel s 64bitovým jádrem, ale žádný takový problém nebyl zaznamenán při použití 32bitového jádra na stejném hardwaru.

Článek vysvětluje, že u 64bitového jádra se mezipaměť nečistých stránek (mezipaměť zpětného zápisu) mohla ve výchozím nastavení zvětšit na 20 % paměti. S 32bitovým jádrem byl efektivně omezen na ~180 MB.

Linus navrhl omezit to na ~180 MB také na 64bitové verzi, ale současný Linux (v4.18) to nedělá. Porovnejte Linusův navrhovaný patch s aktuální funkcí v Linuxu 4.18. Největší argument proti takovým změnám přišel od Davea Chinnera. Poukázal na to, že přílišné omezení ukládání do vyrovnávací paměti by způsobilo, že by souborové systémy trpěly fragmentací. Vysvětlil také, že „pro streamování IO obvykle potřebujeme alespoň
5 s mezipaměti špinavé data k vyrovnání zpoždění.“

Jsem zmatený. Proč zablokování jednotky USB způsobilo zablokování celého systému?

Jsem zmaten, protože jsem četl dřívější článek popisující kód sloučený v roce 2011 (Linux 3.2). Ukazuje to, že jádro mělo řídit mezipaměť nečistých stránek pro jednotlivá zařízení:

Nečisté I/O omezení – LWN.net, 2011

Zde přichází na scénu Fengguangova sada patchů. Pokouší se vytvořit kontrolní smyčku schopnou určit, kolik stránek by měl každý proces v daném okamžiku zašpinit. Procesy, které překračují svůj limit, jsou jednoduše na chvíli uspány, aby je systém zpětného zápisu mohl dohnat.

[…]

Cílem systému je udržet počet špinavých stránek na nastavené hodnotě; pokud se věci vymknou z řady, bude vyvíjeno větší množství síly, aby se věci vrátily tam, kde by měly být.

[…]

Tento poměr však nelze skutečně vypočítat, aniž bychom vzali v úvahu podpůrné zařízení (BDI). Proces může být špinavými stránkami uloženými na daném BDI a systém může mít v tuto chvíli přebytek špinavých stránek, ale rozumnost omezení tohoto procesu závisí také na tom, kolik špinavých stránek pro daný BDI existuje. […] BDI s několika špinavými stránkami dokáže rychle vyčistit své nevyřízené položky, takže si pravděpodobně může dovolit mít jich ještě několik, i když je systém poněkud špinavější, než by se mohlo líbit. Sada patchů tedy vyladí vypočítaný pos_ratio pro konkrétní BDI pomocí složitého vzorce sledujícího, jak daleko je tento konkrétní BDI od svého vlastního nastaveného bodu a jeho pozorované šířky pásma. Konečným výsledkem je upravený pos_ratio popisující, zda by měl systém zašpinit více nebo méně stránek podporovaných daným BDI a o kolik.

Ovládání na zařízení bylo přidáno ještě dříve než toto:Chytřejší omezení zápisu, 2007 LWN.net. [PATCH 0/23] na zařízení špinavé omezení -v10. Byl začleněn do Linux verze 2.6.24.

Přijatá odpověď:

  1. Článek z roku 2013 je chybný
  2. Chyba v LWN? Jste si jistý?
  3. Dlouhé fronty v I/O zařízeních vytvořené zpětným zápisem na pozadí
  4. Omezení „nečistého omezení vstupu/výstupu“?
  5. Skutečné zprávy o problémech se zablokováním USB disku
  6. Limit znečištění byl vypočten nesprávně [2014]
  7. Obrovské blokování alokací stránek na IO [2011]
  8. „Nečisté stránky dosahují konce LRU“? [před rokem 2013]

1. Článek z roku 2013 je chybný

Článek „USB-stick stall“ na vás působí velmi zavádějícím dojmem. Zkresluje původní zprávu i sérii odpovědí.

Artem nehlásil, že celý systém visí, když vyprázdnil zápisy z mezipaměti na USB klíčenku. Jeho původní zpráva si pouze stěžovala, že spuštění příkazu „synchronizace“ může trvat až „desítky minut“. Toto rozlišení je výslovně uvedeno v odpovědi Linuse Torvaldse:

Ve skutečnosti je to opravdu snadné reprodukovat, stačí vzít průměrný
USB klíč a zkusit na něj zapisovat. Právě jsem to udělal s náhodným obrázkem ISO
a je to bolestivé. A není to tak, že by bylo bolestivé dělat
většinu ostatních věcí na pozadí, ale pokud náhodou spustíte
cokoli, co se „synchronizuje“ (a to se děje ve skriptech),
se skřípěním zastaví.
Na minuty.

2. Chyba v LWN? Jste si jistý?

Jon Corbet měl patnáct let zkušeností a každý týden podával zprávy o vývoji linuxového jádra. Očekával jsem, že článek bude alespoň blízký aby to bylo v určitém smyslu správné. Chci tedy zpracovat dva různé záznamy a hledat podrobné body, kde souhlasí nebo nesouhlasí.

Přečetl jsem celou původní diskuzi pomocí archivů na lore.kernel.org. Myslím, že zprávy jsou docela jasné.

Jsem si 100% jistý, že článek špatně interpretuje diskusi. V komentářích pod článkem nejméně dva čtenáři zopakovali nepravdivé tvrzení svými slovy a nikdo je neopravil. Článek pokračuje v tomto zmatku ve třetím odstavci:

Všechna tato data ucpávají I/O fronty a možná zdržují další operace. A jakmile někdo zavolá sync(), věci se zastaví, dokud není zapsána celá fronta.

Může to být zmatek, když Linus říká „ta věc se právě skřípěním zastaví“. „Ta věc“ znamená „cokoli, co se sync “. Ale Corbet píše, jako by „ta věc“ znamenala „celý systém“.

Podle Linuse jde o skutečný problém. Ale naprostá většina „věcí“ ne volání do celosystémové operace sync().[1]

Proč by to Corbet mohl zaměňovat s „celým systémem“? Myslím, že se vyskytla řada problémů a po chvíli je těžké je všechny udržet v hlavě oddělené :-). A přestože LWN popsalo vývoj špinavého throttlingu na zařízení (a na proces), obecně předpokládám, že se o takových detailech moc nepíše. Mnoho dokumentů popisuje pouze nastavení globálního limitu znečištění.

3. Dlouhé fronty v I/O zařízeních vytvořené zpětným zápisem „na pozadí“

Artem zveřejnil ve vláknu druhou zprávu, kde „server se téměř zastaví a dokončení dalších požadavků IO trvá mnohem déle“.

Související:Linux – Směrování přes iptables?

Tato druhá zpráva neodpovídá tvrzením o zavěšení USB flash disku. Stalo se to po vytvoření 10GB souboru na interní disk. Toto je jiný problém.

Zpráva nepotvrdila, zda by se to dalo zlepšit změnou špinavých limitů. A existuje novější analýza takových případů. Při ucpání I/O fronty vašeho hlavního disku nastává významný problém. Na disku, na který se neustále spoléháte, můžete trpět dlouhými prodlevami při načítání programového kódu na vyžádání, ukládání dokumentů a dat aplikací pomocí write() + fsync() atd.

Směrem k méně otravnému zpětnému zápisu na pozadí — LWN.net, 2016

Když se kód správy paměti rozhodne zapsat rozsah špinavých dat, výsledkem je požadavek I/O odeslaný blokovému subsystému. Tento požadavek může strávit nějaký čas v plánovači I/O, ale nakonec je odeslán ovladači pro cílové zařízení.

Problém je v tom, že pokud je k zápisu hodně špinavých dat, může se stát, že na zařízení budou ve frontě čekat obrovské počty (např. tisíce) požadavků. Dokonce i přiměřeně rychlý disk může nějakou dobu trvat, než vyřídí tolik požadavků. Pokud nějaká jiná aktivita (řekněme klepnutí na odkaz ve webovém prohlížeči nebo spuštění aplikace) generuje I/O požadavky na stejném blokovém zařízení, tyto požadavky se přesunou na konec této dlouhé fronty a nemusí být nějakou dobu obsluhovány. Pokud je generováno více synchronních požadavků – například chyby stránek z nově spuštěné aplikace – každý z těchto požadavků bude muset projít touto dlouhou frontou. To je bod, kdy se zdá, že se věci prostě zastaví.

[…]

Většina ovladačů bloků si také interně udržuje vlastní fronty. Tyto fronty nižší úrovně mohou být obzvláště problematické, protože v době, kdy se tam požadavek dostane, již nepodléhá kontrole I/O plánovače (pokud vůbec nějaký I/O plánovač existuje).

Záplaty byly začleněny, aby se to zlepšilo na konci roku 2016 (Linux 4.10). Tento kód je označován jako „škrcení zpětného zápisu“ nebo WBT. Hledání wbt_lat_usec na webu také najde několik dalších příběhů o tom. (Počáteční dokument píše o wb_lat_usec , ale je zastaralý). Uvědomte si, že omezení zpětného zápisu nefunguje s plánovači I/O CFQ nebo BFQ. CFQ je populární jako výchozí plánovač I/O, včetně výchozích sestav jádra až do Linuxu v4.20. CFQ je v jádře v5.0 odstraněno.

Byly provedeny testy, které ilustrovaly problém (a prototypové řešení) jak na SSD (který vypadal jako NVMe), tak na „běžném pevném disku“. Pevný disk „nebyl tak špatný jako zařízení s větší hloubkou fronty, kde máme ohromně přetížené IO“.

Nejsem si jistý těmi „tisíci“ požadavků ve frontě, ale existují přinejmenším zařízení NVMe, která dokážou zařadit stovky požadavků. Většina pevných disků SATA umožňuje zařazení 32 požadavků do fronty („NCQ“). Pevnému disku by samozřejmě dokončení každého požadavku trvalo déle.

4. Omezení „špinavého omezení bez I/O“?

„Ne-I/O špinavé škrcení“ je poměrně složitý systém. Časem byl také upraven. Jsem si jist, že někteří tam byli a stále jsou omezení uvnitř tohoto kódu.

Zápis LWN, komentáře ke kódu/záplatám a snímky z podrobné prezentace ukazují, že bylo zvažováno velké množství scénářů. To zahrnuje notoricky známý pomalý USB klíč v.s. rychlý hlavní pohon. Testovací případy zahrnují frázi „1000 souběžných dd“ (tj. sekvenční zapisovače).

Zatím nevím, jak demonstrovat a reprodukovat jakékoli omezení uvnitř špinavého omezovacího kódu.

Viděl jsem několik popisů oprav problémů, které byly mimo špinavý omezovací kód. Poslední oprava, kterou jsem našel, byla v roce 2014 – viz následující sekce. Ve vláknu, o kterém informuje LWN, se dozvídáme:

V několika posledních vydáních byly problémy, jako je tento,
způsobeny problémy s reclaimem, které už přestalo bavit vidět spoustu špinavých
/ pod zpětným zápisem a skončilo to tak, že čekaly na dokončení IO.

[…] Skript systemtap zachytil tyto typy oblastí a já
věřím, že jsou opraveny.

Mel Gorman také řekl, že existují některé „nevyřešené problémy“.

Stále však existují problémy. Pokud byly všechny špinavé stránky zálohovány pomalým zařízením, pak špinavé omezení nakonec způsobí zablokování vyvážení špinavých stránek […]

Tato pasáž byla jediná věc, kterou jsem našel v hlášeném diskusním vláknu, které se blíží zálohování interpretace LWN. Přál bych si, abych porozuměl tomu, na co to odkazovalo :-(. Nebo jak to demonstrovat a proč se to nezdálo jako významný problém v testech, které Artem a Linus provedli.

5. Skutečné zprávy o problémech „zablokování USB disku“

Ačkoli Artem ani Linux nehlásili „zablokování USB disku“, které ovlivnilo celý systém, můžeme o tom najít několik zpráv jinde. To zahrnuje zprávy z posledních let – dlouho po poslední známé opravě.

nevím jaký je v tom rozdíl. Možná se jejich testovací podmínky nějakým způsobem lišily, nebo možná byly v jádře vytvořeny nějaké nové problémy od roku 2013…

  • https://utcc.utoronto.ca/~cks/space/blog/linux/USBDrivesKillMyPerformance / https://utcc.utoronto.ca/~cks/space/blog/linux/FixingUSBDriveResponsiveness [2017]
  • Proč můj počítač zamrzá, když kopíruji soubor na pendrive? [leden 2014]
  • Systém se zpožďuje při provádění velkých R/W operací na externích discích [2018]
  • Linuxové grafické uživatelské rozhraní velmi nereaguje, když provádíte I/O těžkého disku – co vyladit? [2019]

6. Limit znečištění byl vypočten nesprávně [2014]

V lednu 2014 došlo k zajímavé opravě (aplikované v jádře v3.14). V otázce jsme uvedli, že výchozí limit byl nastaven na 20 % paměti. Ve skutečnosti je nastaveno na 20 % paměti, která je k dispozici pro cache špinavých stránek. Například vyrovnávací paměti jádra odeslaly data pro síťové sokety TCP/IP. Vyrovnávací paměti soketů nelze zahodit a nahradit je špinavou mezipamětí stránek :-).

Problém byl v tom, že jádro počítalo swapovatelnou paměť, jako by mohlo vyměnit data ve prospěch špinavé mezipaměti stránek. Ačkoli je to teoreticky možné, jádro je silně zaujaté, aby se vyhnulo swapování, a místo toho dává přednost vypuštění mezipaměti stránek. Tento problém byl ilustrován – hádejte co – testem zahrnujícím zápis na pomalou USB klíčenku a zjištění, že to způsobovalo zablokování v celém systému :-).

Související:Linux – Proč přesměrovat výstup na 2>&1 a 1>&2?

Viz Re:[patch 0/2] mm:omezte rekultivační stáje s těžkou anonovou a špinavou cache

Oprava je, že dirty_ratio je nyní považováno pouze za podíl mezipaměti souborů.

Podle vývojáře jádra, který tímto problémem trpěl, „spouštěcí podmínky vypadají docela věrohodně – vysoké využití anon paměti s konfigurací těžkého bufferovaného IO a swapu – a je vysoce pravděpodobné, že se to děje ve volné přírodě.“ Takže to může být některé uživatelské zprávy kolem roku 2013 nebo dříve.

7. Obrovské blokování alokací stránek na IO [2011]

To byl další problém:Obrovské stránky, pomalé disky a dlouhá zpoždění (LWN.net, listopad 2011). Tento problém s velkými stránkami by měl být nyní vyřešen.

Navzdory tomu, co článek říká, si také myslím, že většina současných počítačů se systémem Linux ve skutečnosti nepoužívá velké stránky. To se může počínaje Debianem 10 měnit. Nicméně i když Debian 10 začne přidělovat velké stránky, kde je to možné, zdá se mi jasné, že nebude způsobovat žádná zpoždění, pokud nezměníte jiné nastavení zvané defrag na „vždy“.

8. „Nečisté stránky dosahující konce LRU“ [před rokem 2013]

Nezkoumal jsem to, ale přišlo mi to zajímavé:

mgorman 2011:Toto je nový typ zablokování souvisejícího s USB, protože je způsobeno synchronním komprimačním zápisem, kde stejně jako v minulosti byly velkým problémem špinavé
stránky, které dosáhly konce LRU a byly zapsány regenerací .

mgorman 2013:Práce v této obecné oblasti se zabývala
takovými problémy, jako jsou špinavé stránky dosahující konce LRU (nadměrné využití CPU
)

Pokud se jedná o dva různé problémy „dosažení konce LRU“, pak první zní, že by mohl být velmi špatný. Zní to, jako když se špinavá stránka stane nejméně nedávno používanou stránkou, jakýkoli pokus o alokaci paměti bude zpožděn, dokud se nedokončí zápis této špinavé stránky.

Ať už to znamená cokoli, říká, že problém je nyní vyřešen.

[1] Jedna výjimka:na chvíli správce balíčků Debian dpkg používá synchronizaci () ke zlepšení výkonu. Toto bylo odstraněno kvůli přesnému problému, že sync() může trvat extrémně dlouho. Přešli na přístup pomocí sync_file_range() na Linuxu. Viz chyba Ubuntu #624877, komentář 62.

Část předchozího pokusu o odpověď na tuto otázku – to by mělo být většinou nadbytečné:

Myslím, že obě Artemovy zprávy můžeme vysvětlit tak, že jsou v souladu s kódem „Ne-I/O špinavé omezení“.

Cílem špinavého omezovacího kódu je umožnit každému podpůrnému zařízení spravedlivý podíl z „celkové mezipaměti pro zpětný zápis“, „která se vztahuje k jeho aktuální průměrné rychlosti zápisu ve vztahu k ostatním zařízením“. Tato fráze pochází z dokumentace /sys/class/bdi/.[2]

V nejjednodušším případě se zapisuje pouze na jedno podpůrné zařízení. V takovém případě je spravedlivý podíl zařízení 100 %. Volání write() jsou omezena, aby řídila celkovou mezipaměť zpětného zápisu a udržovala ji na „nastavené hodnotě“.

Zápisy začnou být omezeny v polovině mezi dirty_background_ratio – bod, který spouští zápis na pozadí – a dirty_ratio – pevný limit mezipaměti zpětného zápisu. Ve výchozím nastavení se jedná o 10 % a 20 % dostupné paměti.

Stále můžete například zaplnit až 15 % zápisu pouze na váš hlavní disk. Můžete mít gigabajty zápisů v mezipaměti podle toho, kolik máte RAM. V tu chvíli začnou být volání write() omezována, aby odpovídala rychlosti zpětného zápisu – ale to není problém. Očekávám, že problémy se zablokováním se týkají volání read() a fsync(), která uvíznou za velkým množstvím nesouvisejících IO. Toto je specifický problém, který řeší kód „omezování zpětného zápisu“. Některé odeslané opravy WBT obsahují popisy problémů, které ukazují strašlivá zpoždění, která to způsobuje.

Podobně byste mohli celých 15 % naplnit zápisy na USB klíčenku. Další zápisy na USB budou omezeny. Ale hlavní disk by nevyužil nic ze svého spravedlivého podílu. Pokud začnete volat write() na vašem hlavním souborovém systému, nebude to omezeno, nebo bude alespoň zpožděno mnohem méně. A myslím, že zápisy do USB by byly omezeny ještě více, aby byly tyto dva zapisovače v rovnováze.

Očekávám, že celková mezipaměť zpětného zápisu by se mohla dočasně zvýšit nad nastavenou hodnotu. V některých náročnějších případech můžete narazit na pevný limit celkové mezipaměti zpětného zápisu. Výchozí pevný limit je 20 % dostupné paměti; možnost konfigurace je dirty_ratio / dirty_bytes . Možná se vám to podaří, protože zařízení se může zpomalit (možná kvůli náhodnějšímu vzoru I/O) a špinavé omezování nepozná změnu rychlosti okamžitě.

[2] Možná si všimnete, že tento dokument naznačuje, že můžete ručně omezit poměr mezipaměti zpětného zápisu, kterou lze použít pro konkrétní oddíl/systém souborů. Nastavení se nazývá /sys/class/bdi/*/max_ratio . Uvědomte si, že „pokud je zařízení, které chcete omezit, jediné, do kterého je aktuálně zapsáno, omezení nemá velký vliv.“


Linux
  1. Odstraňování problémů se systémem Linux 101:Výkon systému

  2. Jak změnit identitu systému Linux

  3. Linux – Proč v systému není přítomen žádný souborový systém Rootfs?

  1. Jak zkontrolovat verzi OS a Linuxu

  2. Linux – Proč Linux Utils nepoužívají systémové volání k získání aktuálního času?

  3. Zkontrolujte zatížení systému v systému Linux

  1. Jaká je aktuální úroveň běhu systému Linux?

  2. Proč následující příkaz zabíjí systém?

  3. Linux – Proč nemůže jádro spustit inicializaci?