Hlavní navigace

Co před námi tají /proc (16)

6. 9. 2001
Doba čtení: 6 minut

Sdílet

Dneska začneme písmeno S. Podíváme se hlavně na obsah poměrně obsáhlého souboru slabinfo. No a zbytek si necháme na příště.

Jak velí tradice, nejprve výpis základního adresáře /proc. Tečka před názvem znamená, že už to máme za sebou:

  .840     .devices     .kcore   .modules     stat     ide/     acpi/
  .842     .dma         .kmsg    .mounts      swaps    irq/
  .847     .execdomains .ksyms   .mtrr        uptime   net/
  .848     .filesystems .loadavg .partitions  version  nv/
  .849     .interrupts  .locks   .pci         bus/     sys/
  .cmdline .iomem       .meminfo  self@       driver/  sysvipc/
  .cpuinfo .ioports     .misc     slabinfo    fs/      tty/
self

Tohle bude asi nejjednodušší popis z celého seriálu. self je symbolický link na adresář s informacemi pro proces, který vyvolal čtení obsahu adresáře /proc.

sioux@sirion /proc $ls -l /proc/self &
[1] 1063
lrwxrwxrwx  1 root root    64 zář  3 16:53 /proc/self -> 1063
[1]+  Done  ls -l /proc/self

Na tomto výpisu příkazu ls je to dobře vidět. Na druhém řádku vypíše proces PID procesu, který je spouštěn na pozadí. Potom příkaz ls vypíše aktuální hodnotu linku self. Provedeme-li to samé ještě jednou, bude hodnota PID na druhém řádku jiná:

sioux@sirion /proc $ls -l /proc/self &
[1] 1064
lrwxrwxrwx  1 root root    64 zář  3 16:53 /proc/self -> 1064
[1]+  Done  ls -l /proc/self

Vše o tom, co je vlastně obsahem adresáře číslo 1063 (resp. 1064), tedy informace o procesu s daným PID, naleznete hned v prvním dílu našeho seriálu.

slabinfo

Jak již bylo řečeno výše, je tohle jeden ze souborů v adresáři /proc, kde toho lze nalézt opravdu hodně. Proto bude i ukázkový výpis opravdu hodně dlouhý. Abychom se v něm hned neztratili (ale raději až za chvilku), rozdělím ho na několik dílů, vždy po skupině informací logicky patřících k sobě, a budu je uvádět vždy u vysvětlení patřičné části.

Základem našeho bádání bude, co to vlastně je ten SLAB. Slovo slab v angličtině znamená v tomto případě asi nejlépe tabulka. Jedná se o speciální druh alokátoru. Alokátor je mechanismus k získávání bloku adres z celého adresového prostoru. Alokátor může alokovat fyzickou paměť, virtuální paměť, datové bloky na disku nebo třeba místo ve swapu. Prostě zavoláte rutiny alokátoru alloc_somethin­g(velikost_jed­notky, počet_jednotek) a on vám vrátí adresu, od které máte od toho okamžiku dovoleno používat požadovaný rozsah adres a objektů na ně mapovaných. Po použití tuto oblast zase uvolníte použitím jiné rutiny. To je všechno asi hodně obecné, tak nějaký konkrétní příklad. Rutinami alokátoru jsou třeba funkce z libc – malloc() a odpovídající free(). Případně v C++ jsou to operátory new a delete. Vždy se tedy jedná o to, spravovat určitý rozsah prostředků a na požádání je co nejlépe rozdělovat mezi zájemce.

Postupně se přišlo na to, že operace alokování jsou potřeba v operačních systémech na různých místech (jak bylo nastíněno výše). Proto se návrháři pro zjednodušení rozhodli vytvořit obecný mechanismus alokátoru použitelný potom pro jekýkoliv konkrétní úkol. Testováním se ukázalo, že tato společná komponenta má v celém operačním systému nezanedbatelný vliv na souhrnný výkon. Proto bylo vhodné zjistit, jak by šlo alokátor optimalizovat a tím zlepšit výkon celého operačního systému. Práci alokátoru (pro konkrétní objekt) lze rozdělit na dvě části. Prvním úkolem je získat potřebnou oblast (předpokládejme jako model paměťový alokátor – tedy oblast paměti). Jakmile je jasné, který úsek bude použit, začíná druhá fáze. Zde je nutno objekt inicializovat. V případě paměti to nemusí být na první pohled zřejmé. Prostě uživateli předám adresu paměti, kterou chtěl, a hotovo. Tak jednoduché to ale zase není. Jádro si musí udržovat přehled o tom, které části paměti jsou obsazeny, kým a za jakým účelem. To v tomto případě platí jak pro skutečnou fyzickou paměť, tak pro oblast ve virtuální paměti, kam bude nový úsek zamapován. Administrativa kolem údržby těchto informací může být dosti složitá. U specializovaných objektů jako objekty souborů, adresářových cest a dalších je čas strávený přípravou objektu zase mnohem delší než samotná alokace prostoru. Naopak při dealokaci by měl slušný systém (takový, který aspiruje na vyšší bezpečnostní třídy – jako C2 dle Orange Book) splňovat vlastnost znovupoužitelnosti, a tedy objekty před vrácením nulovat. I pokud tomu tak není, bez dalších opatření musíme stejně při alokaci celý objekt přepsat, nebo se minimálně nespoléhat na to, že má nějaký konkrétní obsah.

A tady se dostáváme k jádru věci. Je možné udržovat speciální (tzn. oddělený) alokační mechanismus (respektive jeho jednu část) a objekty kešovat. Pokud bude někdo chtít stránku paměti a pak ji zase vrátí, je dobré vědět, že to byla stránka paměti pro uživatele a, až zase bude nějakou chtít, znovupoužít tuhle stránku. Tím se dají využít části (minimálně) informací zpracovávaných při administrativě a alokace může být rychlejší. Samozřejmě, že i zde může být požadavek na znovupoužitelnost, ale pokud například generuji síťové pakety, je zde řada informací, která je pro všechny (nebo skupinu) stejná a je bezpečné ji ponechat nesmazanou. Ostatní (důvěrné) informace se samozřejmě promáznou.

Mechanismus alokace a dealokace objektů se potom změní na následující:

Alokace:

if (požadovaný objekt je v cache) {
  vyber objekt z cache
} else {
  alokuj paměť
  vytvoř (inicializuj) objekt
}

Dealokace:

vrať objekt do cache (nic se neuvolňuje)

V Linuxu existují tyto odělené cache: vm_area, mm, names, filp, dquot, bh, sigact a dentry. Postupně se dostanemek tomu, pro co se používají. Nejprve, jak jsou tyto cache v Linuxu organizovány. Každá cache se skládá z několika „slabů“ (tedy tabulek). Ty bývají zarovnány nejlépe na velikost stránky nebo podobnou vhodnou konstantu a obsahují pevně definovaný počet objektů daného typu. Každý slab může být v jednom ze tří stavů. Zcela prázdný, kdy z něj není alokován žádný objekt, částečně využit, kdy je alokováno méně objektů, než je celková kapacita, a nakonec samozřejmě plný, když jsou alokovány všechny jeho objekty. Pokud je potřeba alokovat nový objet, použije se nejprve slab s částečným zaplněním, pokud takový není, tak zcela prázdný. Naopak při uvolňování se uvolní objekt ze slabu, který je poloprázný (nejlépe s nejmenším počtem objektů), a pokud není, tak ze zcela zaplněného slabu. To má jediný důvod. Jakýkoli obsazený slab je vlastně aktivní stránka paměti. A čím méně je takovýchto stánek použito, tím je systém alokátoru efektivnější (a pravděpodobně také rychlejší).

Teď si tedy vysvětlíme použití jednotlivých typů cache. vm_area slouží pro oblasti viruální paměti, mm pro fyzické stránky, names pro absolutní jména souborů kopírovaná do adresového prostoru jádra, filp pro informace o (otevřených) souborech, dquot pro (diskové) quoty, bh pro buffery k diskovým operacím, sigact je pro administrativu kolem signálů (rozhraní sigaction) a dentry je pro adresářovou cache (vyhledávání cest k souborům).

Tak to bylo letecky pro odstrašení nepřátel :) a teď k jednotlivým položkám výpisu našeho souboru. Nejprve nejjednodušší první řádek. Verze je zakompilovaná napevno. Za ní se mohou objevit ještě atributy, a to (SMP) pro víceprocesorové systémy, kde je o něco více informací, a potom (statistics), pokud si explicitně zapnete generování podrobných informací. To lze provést v souboru mm/slab.c, kde na řádku číslo 89 (v 2.4.9) je definice makra preprocesoru STATS. Je-li hodnota 0, nic se negeneruje, je-li 1, jsou generovány další podrobnější informace. V souboru je v tomto místě i další popis ohledně nastavení ladění a podrobnosti výpisů.

slabinfo - version: 1.1
...

Od dalších řádek jsou informace pro jednotlivé druhy cache. Je zde vždy název a potom následující parametry: počet aktivních objektů, počet celkových objektů, velikost objektu, počet aktivních slabů, celkový počet slabů a počet stránek (4KB) na jeden slab u tohoto typu:

...
kmem_cache            54     78    100    2    2    1
...

Myslím, že pro dnešek toho bylo dost, takže jednotlivé typy slabů a jejich význam si necháme na příště. Pokud by měl někdo zájem o podrobné informace o teorii a implementaci slabu v SunOS 5.4, může si z mé stránky stáhnout tento dokument.

Byl pro vás článek přínosný?