Sdílet prostřednictvím


Run-Down Ochrana

Ovladače v režimu jádra mohou pomocí ochrany před vyčerpáním bezpečně přistupovat k objektům ve sdílené systémové paměti, které jsou vytvářeny a mazány jiným ovladačem v režimu jádra.

Objekt se říká, že je spuštěn, pokud jsou dokončeny všechny nevyřízené přístupy objektu a nebudou uděleny žádné nové žádosti o přístup k objektu. Například sdílený objekt může být potřeba uvolnit, aby mohl být odstraněn a nahrazen novým objektem.

Ovladač, který vlastní sdílený objekt, může ostatním ovladačům umožnit získat a uvolnit ochranu proti ukončení objektu. Pokud je ochrana před vypnutím aktivní, může ovladač jiný než vlastník přistupovat k objektu bez rizika, že by vlastník objekt odstranil dříve, než bude přístup dokončen. Než se přístup spustí, přístupový ovladač požádá o ochranu proti ukončení objektu. U dlouhodobého objektu je tento požadavek téměř vždy udělen. Po dokončení přístupu uvolní přístupový ovladač jeho předtím získanou ochranu před demontáží na objektu.

Rutiny ochrany před primárním výpadkem

Chcete-li začít sdílet objekt, ovladač, který vlastní objekt, volá rutinu ExInitializeRundownProtection pro inicializaci ochrany před vypršením na objektu. Po tomto volání mohou ostatní ovladače, které přistupují k objektu, získat a uvolnit ochranu proti vyřazení objektu.

Ovladač, který přistupuje ke sdílenému objektu, volá rutinu ExAcquireRundownProtection pro vyžádání ochrany proti spuštění objektu. Po dokončení přístupu tento ovladač volá rutinu ExReleaseRundownProtection k uvolnění ochrany proti vyčerpání objektu.

Pokud vlastnící ovladač zjistí, že sdílený objekt musí být odstraněn, tento ovladač čeká na odstranění objektu, dokud se nedokončí všechny nevyřízené přístupy k objektu.

Při přípravě na odstranění sdíleného objektu volá vlastnící ovladač rutinu ExWaitForRundownProtectionRelease , která čeká na spuštění objektu. Během tohoto volání ExWaitForRundownProtectionRelease čeká na uvolnění všech dříve poskytnutých instancí ochrany uzavření na objektu a zároveň brání udělení nových požadavků na tuto ochranu. Po dokončení posledního chráněného přístupu a po uvolnění všech instancí ochrany vyřazení se ExWaitForRundownProtectionRelease vrátí a vlastní ovladač může bezpečně odstranit tento objekt.

ExWaitForRundownProtectionRelease blokuje běh vlákna volajícího ovladače, dokud všechny ovladače, které drží run-down ochranu na sdíleném objektu, tuto ochranu neuvolní. Aby se zabránilo tomu, že ExWaitForRundownProtectionRelease blokuje provádění po nadměrně dlouhou dobu, měly by se vlákna ovladače, která přistupují ke sdílenému objektu, vyhnout pozastavení, zatímco mají ochranu před ukončením na objektu. Z tohoto důvodu by přístupové ovladače měly volat ExAcquireRundownProtection a ExReleaseRundownProtection v kritické oblasti nebo chráněné oblasti, nebo při běhu na IRQL = APC_LEVEL.

Použití ochrany proti vybití.

Ochrana za běhu je užitečná pro poskytování přístupu ke sdílenému objektu, který je téměř vždy dostupný, ale může být občas potřeba odstranit a nahradit. Ovladače, které přistupují k datům nebo volají rutiny v tomto objektu, se po odstranění nesmí pokusit o přístup k objektu. Jinak můžou tyto neplatné přístupy způsobit nepředvídatelné chování, poškození dat nebo dokonce selhání systému.

Například antivirový ovladač obvykle zůstává v paměti, když je operační systém spuštěný. Někdy může být nutné tento ovladač uvolnit a nahradit aktualizovaným vydáním ovladače. Ostatní ovladače odesílají do antivirového ovladače vstupně-výstupní požadavky pro přístup k datům a rutinám v tomto ovladači. Před odesláním žádosti o vstupně-výstupní operace může komponenta jádra, jako je správce filtru systému souborů, získat ochranu proti předčasnému uvolnění antivirového ovladače, zatímco zpracovává vstupně-výstupní požadavek. Po dokončení V/V požadavku je možné uvolnit ochranu proti vybití.

Ochrana před opotřebením neseríalizuje přístupy ke sdílenému objektu. Pokud dva nebo více přístupových ovladačů může současně držet ochranu vypnutí objektu a přístupy k objektu musí být serializovány, musí být použit nějaký jiný mechanismus, například zámek pro vzájemné vyloučení, k serializaci přístupů.

Struktura EX_RUNDOWN_REF

Struktura EX_RUNDOWN_REF sleduje stav ochrany před vypnutím u sdíleného objektu. Tato struktura je neprůhlená pro ovladače. Rutiny ochrany vyčerpání dodávané systémem používají tuto strukturu ke spočítání počtu instancí ochrany vyčerpání, které jsou v současné době platné pro objekt. Tyto rutiny také používají tuto strukturu ke sledování, zda je objekt spuštěn nebo je v procesu spuštění.

Chcete-li začít sdílet objekt, ovladač, který vlastní objekt, volá ExInitializeRundownProtection, aby inicializoval strukturu EX_RUNDOWN_REF přidruženou k objektu. Po inicializaci může vlastnící ovladač zpřístupnit tuto strukturu jiným ovladačům, které vyžadují přístup k objektu. Přístupové ovladače předávají tuto strukturu jako parametr při volání funkcí ExAcquireRundownProtection a ExReleaseRundownProtection, které získávají a uvolňují ochranu proti rundown na objektu. Vlastní ovladač předá tuto strukturu jako parametr volání ExWaitForRundownProtectionRelease, které čeká na ukončení objektu, aby mohl být bezpečně smazán.

Porovnání zámků

Ochrana před nekontrolovaným přístupem je jedním z několika způsobů, jak zaručit bezpečný přístup ke sdílenému objektu. Dalším přístupem je použití softwarového zámku vzájemného vyloučení. Pokud ovladač vyžaduje přístup k objektu, který je aktuálně uzamčen jiným ovladačem, musí první ovladač počkat, až druhý ovladač uvolní zámek. Získání a uvolnění zámků se ale může stát kritickým bodem výkonu a zámky můžou spotřebovávat velké množství paměti. Pokud se používá nesprávně, zámky můžou způsobit zablokování ovladačů, které soupeří o stejné sdílené objekty. Úsilí o zjišťování a zabránění zablokování obvykle vyžaduje značné množství výpočetních prostředků.

Na rozdíl od zámků má ochrana proti úpadku relativně nízké nároky na čas zpracování a paměť. Jednoduchý počet odkazů je přidružen k objektu, aby se zajistilo, že odstranění objektu je opožděno, dokud nejsou dokončeny všechny nevyřízené přístupy k objektu. Díky tomuto přístupu je možné místo zámků softwaru vzájemného vyloučení použít atomické hardwarové instrukce, které zaručují bezpečný přístup k objektu. Volání pro získání a uvolnění ochrany před ukončením jsou rychlá obvykle. Výhody použití lehkého mechanismu, jako je ochrana proti vybití, mohou být významné pro sdílený objekt, který má dlouhou životnost a je sdílen mezi mnoha ovladači.

Další rutiny ochrany proti vybití

K dispozici je několik dalších rutin pro ochranu před selháním, kromě těch, které byly zmíněny dříve. Tyto dodatečné rutiny mohou používat některé ovladače.

Rutina ExReInitializeRundownProtection umožňuje, aby dříve použitá struktura EX_RUNDOWN_REF byla přidružena k novému objektu a inicializuje ochranu spuštění na tomto objektu.

Rutina ExRundownCompletedaktualizuje EX_RUNDOWN_REF strukturu , která indikuje, že spuštění přidruženého objektu bylo dokončeno.

Rutiny ExAcquireRundownProtectionEx a ExReleaseRundownProtectionEx jsou podobné rutinám ExAcquireRundownProtection a ExReleaseRundownProtection. Tyto čtyři rutiny inkrementují nebo dekrementují počet instancí ochrany před vypršením, které jsou v platnosti na daný sdílený objekt. Zatímco ExAcquireRundownProtection a ExReleaseRundownProtection inkrementují a dekrementují toto počítání o jeden, ExAcquireRundownProtectionEx a ExReleaseRundownProtectionEx inkrementují a dekrementují počítání o libovolné hodnoty.

Ochrana při postupném vypínání citlivá na mezipaměť

Rundown reference je kompaktní a rychlá datová struktura, ale může způsobit soutěžení o cache, když se mnoho procesorů pokusí získat referenci současně. To může ovlivnit výkon a škálovatelnost ovladače.

Chcete-li se tomuto problému vyhnout, můžete použít cache-sensitivní uzavírací referenci k distribuci sledování odkazů napříč více řádky mezipaměti. Tím se sníží kolize mezipaměti a zvýší se výkon ovladače na počítačích s více procesory.

Pokud chcete použít referenční informace ke spuštění s podporou mezipaměti, postupujte takto:

  1. Vytvořte objekt EX_RUNDOWN_REF_CACHE_AWARE jedním z následujících způsobů:
  2. Před přístupem k objektu zajistěte ochranu před zrušením voláním rutiny ExAcquireRundownProtectionCacheAware. Tato rutina vrátí hodnotu PRAVDA, pokud je požadavek udělen, nebo NEPRAVDA, pokud je objekt ukončován.
  3. Po přístupu k objektu uvolněte ochranu rundown voláním rutiny ExReleaseRundownProtectionCacheAware.
  4. Před odstraněním objektu počkejte, než se objekt spustí voláním rutiny ExWaitForRundownProtectionReleaseCacheAware . Tato rutina blokuje aktuální vlákno, dokud nebudou vydány všechny instance ochrany rundownu u objektu.
  5. Pokud ovladač dříve zavolal ExAllocateCacheAwareRundownProtection, měl by zavolat ExFreeCacheAwareRundownProtection, aby uvolnil rundown reference.

Pro opětovné použití mezipaměťově citlivého kontrolního bodu, postupujte takto:

  1. Po volání funkce ExWaitForRundownProtectionReleaseCacheAware zavolejte ExRundownCompletedCacheAware k označení, že vyprázdnění starého objektu bylo dokončeno.
  2. Volání ExReInitializeRundownProtectionCacheAware k opětovné inicializaci odkazu po spuštění přidruženého objektu.
  3. Ovladač teď může znovu volat ExAcquireRundownProtectionCacheAware.

Referenční ukazatel optimalizovaný pro mezipaměť má výhodu lepšího výkonu a škálovatelnosti v konkrétních situacích, ale spotřebovává více paměti než běžný odkaz na uvolnění. Tento kompromis byste měli vzít v úvahu při výběru mezi dvěma typy odkazů na rundown.