Dela via


Run-Down Skydd

Drivrutiner i kernelläge kan använda nedstängningsskydd för att på ett säkert sätt komma åt objekt i delat systemminne som skapas och tas bort av en annan drivrutin i kernelläge.

Ett objekt sägs vara nedkört om alla utestående åtkomster till objektet har slutförts och inga nya begäranden om åtkomst till objektet beviljas. Ett delat objekt kan till exempel behöva köras ned så att det kan tas bort och ersättas med ett nytt objekt.

Drivrutinen som äger det delade objektet kan möjliggöra för andra drivrutiner att hämta och frigöra avstängningsskydd för objektet. När nedstängningsskyddet är i kraft kan en annan användare än ägaren komma åt objektet utan risk för att ägaren tar bort objektet innan åtkomsten slutförs. Innan åtkomsten börjar, begär åtkomstdrivrutinen ett nedräckningsskydd för objektet. För ett objekt med lång livslängd beviljas den här begäran nästan alltid. När åtkomsten har slutförts släpper den åtkommande drivrutinen sitt tidigare förvärvade nedräkningsskydd för objektet.

Primära rutiner för nedkörningsskydd

Om du vill börja dela ett objekt anropar drivrutinen som äger objektet rutinen ExInitializeRundownProtection för att initiera nedkörningsskydd för objektet. Efter det här anropet kan andra drivrutiner som har åtkomst till objektet erhålla och frigöra nedtypningsskydd för objektet.

En drivrutin som kommer åt det delade objektet anropar rutinen ExAcquireRundownProtection för att begära körningsskydd för objektet. När åtkomsten är klar anropar den här drivrutinen rutinen ExReleaseRundownProtection för att frigöra körningsskydd för objektet.

Om den ägande drivrutinen fastställer att det delade objektet måste tas bort väntar drivrutinen på att ta bort objektet tills alla utestående åtkomster för objektet har slutförts.

Som förberedelse för att ta bort det delade objektet anropar den ägande drivrutinen rutinen ExWaitForRundownProtectionRelease för att vänta på att objektet ska avslutas. Under det här anropet väntar ExWaitForRundownProtectionRelease på att alla tidigare beviljade instanser av nedkörningsskydd på objektet ska släppas, men förhindrar att nya begäranden om nedkörningsskydd för objektet beviljas. När den sista skyddade åtkomsten har slutförts och alla instanser av nedstängningsskydd har släppts, returnerar ExWaitForRundownProtectionRelease och den ägande drivrutinen kan ta bort objektet på ett säkert sätt.

ExWaitForRundownProtectionRelease blockerar körningen av den anropande drivrutinstråden tills alla drivrutiner som har körskydd på det delade objektet släpper det här skyddet. För att förhindra att ExWaitForRundownProtectionRelease hindrar utförandet under alltför långa perioder bör drivrutiners trådar som har åtkomst till det delade objektet inte pausas medan de har nedstängningsskydd på objektet. Därför bör åtkomst till drivrutiner anropa ExAcquireRundownProtection och ExReleaseRundownProtection i en kritisk region eller skyddad region, eller när de körs på IRQL = APC_LEVEL.

Användningsområden för urladdningsskydd

Skydd mot avstängning är användbart för att ge åtkomst till ett delat objekt som nästan alltid finns tillgängligt, men som ibland kan behöva tas bort och ersättas. Drivrutiner som har åtkomst till data eller som anropar rutiner i det här objektet får inte försöka komma åt objektet när det har tagits bort. Annars kan dessa ogiltiga åtkomster orsaka oförutsägbart beteende, skadade data eller till och med systemfel.

Till exempel förblir en antivirusdrivrutin vanligtvis inläst i minnet när operativsystemet körs. Ibland kan den här drivrutinen behöva tas bort och ersättas med en uppdaterad version av drivrutinen. Andra drivrutiner skickar I/O-begäranden till antivirusdrivrutinen för att få åtkomst till data och rutiner i den här drivrutinen. Innan du skickar en I/O-begäran kan en kernelkomponent, till exempel en filterhanterare för filsystem, skaffa run-down-skydd för att skydda mot för tidig avlastning av antivirusdrivrutinen medan den hanterar I/O-begäran. När I/O-begäran har slutförts kan nedstängningsskyddet frisläppas.

Körningsskydd serialiserar inte åtkomst till ett delat objekt. Om två eller flera drivrutiner samtidigt kan ha avstängningsskydd på ett objekt och åtkomsten till objektet måste serialiseras, måste någon annan mekanism, till exempel ett lås för ömsesidig uteslutning, användas för att serialisera åtkomsterna.

Strukturen EX_RUNDOWN_REF

En EX_RUNDOWN_REF struktur spårar statusen för nedbrytningsskydd på ett delat objekt. Den här strukturen är ogenomskinlig för drivrutiner. De systemlevererade rutinerna för nedkörningsskydd använder den här strukturen för att räkna antalet instanser av nedkörningsskydd som för närvarande är i effekt på objektet. De här rutinerna använder också den här strukturen för att spåra om objektet körs ned eller är i processen att köras ned.

Om du vill börja dela ett objekt anropar drivrutinen som äger objektet ExInitializeRundownProtection för att initiera den EX_RUNDOWN_REF struktur som är associerad med objektet. Efter initieringen kan ägande drivrutinen göra den här strukturen tillgänglig för andra drivrutiner som kräver åtkomst till objektet. De åtkomstdrivrutiner skickar den här strukturen som en parameter till ExAcquireRundownProtection och ExReleaseRundownProtection-anropen som förvärvar och släpper körningsskydd för objektet. Den ägande drivrutinen skickar den här strukturen som en parameter till anropet ExWaitForRundownProtectionRelease som väntar på att objektet ska köras ned för att det ska kunna tas bort på ett säkert sätt.

Jämförelse med lås

Nedkörningsskydd är ett av flera sätt att garantera säker åtkomst till ett delat objekt. En annan metod är att använda ett programvarulås för ömsesidig uteslutning. Om en drivrutin kräver åtkomst till ett objekt som för närvarande är låst av en annan drivrutin måste den första drivrutinen vänta tills den andra drivrutinen släpper låset. Att hämta och frigöra lås kan dock bli en flaskhals för prestanda och lås kan förbruka stora mängder minne. Om de används felaktigt kan lås orsaka att drivrutiner som konkurrerar om samma delade objekt blir låsta. För att identifiera och undvika dödlägen krävs vanligtvis avledning av betydande databehandlingsresurser.

Till skillnad från lås har överbelastningsskydd relativt låg bearbetningstid och minnesbehov. Ett enkelt referensantal är associerat med objektet för att säkerställa att borttagningen av objektet skjuts upp tills alla utestående åtkomster för objektet har slutförts. Med den här metoden kan atomiska, sammankopplade maskinvaruinstruktioner användas i stället för programlås med ömsesidig uteslutning för att garantera säker åtkomst till ett objekt. Anrop för att hämta och släppa run-down-skydd är vanligtvis snabba. Fördelarna med att använda en lättviktsmekanism, såsom nedkörningsskydd, kan vara betydande för en delad resurs som har lång livslängd och delas mellan många förare.

Andra rutiner för nedkörningsskydd

Flera andra rutiner för nedkörningsskydd är tillgängliga, förutom de som nämndes tidigare. Dessa extra rutiner kan användas av vissa drivrutiner.

Med rutinen ExReInitializeRundownProtection kan en tidigare använd EX_RUNDOWN_REF-struktur associeras med ett nytt objekt och initierar nedkörningsskydd för det här objektet.

Rutinen ExRundownCompleted uppdaterar EX_RUNDOWN_REF struktur för att indikera att körningen av det associerade objektet har slutförts.

Rutinerna ExAcquireRundownProtectionEx och ExReleaseRundownProtectionEx liknar ExAcquireRundownProtection och ExReleaseRundownProtection. Dessa fyra rutiner ökar eller minskar antalet instanser av avvecklingsskydd som är aktiva på ett gemensamt objekt. Medan ExAcquireRundownProtection och ExReleaseRundownProtection ökar och minskar antalet med en, ökar och minskar ExAcquireRundownProtectionEx och ExReleaseRundownProtectionEx antalet med godtyckliga belopp.

Cachemedvetet nedbrytningsskydd

En rundown-referens är en kompakt och snabb datastruktur, men den kan orsaka cachekonkurrens när många processorer försöker hämta referensen samtidigt. Detta kan påverka drivrutinens prestanda och skalbarhet.

För att undvika det här problemet kan du använda en cachemedveten rundown-referens för att distribuera referensspårningen över flera cacherader. Detta minskar cachekonkurrationen och förbättrar drivrutinens prestanda på datorer med flera processorer.

Följ dessa steg om du vill använda en cachemedveten rundown-referens:

  1. Skapa ett EX_RUNDOWN_REF_CACHE_AWARE objekt genom att göra något av följande:
  2. Begär rundown-skydd för objektet innan du kommer åt det genom att anropa rutinen ExAcquireRundownProtectionCacheAware . Den här rutinen returnerar TRUE om begäran beviljas eller FALSE om objektet körs ned.
  3. Frigör rundown-skydd för objektet när det har använts genom att anropa rutinen ExReleaseRundownProtectionCacheAware .
  4. Vänta tills objektet avslutas innan du tar bort det genom att anropa rutinen ExWaitForRundownProtectionReleaseCacheAware. Den här rutinen blockerar den aktuella tråden tills alla instanser av nedkört skydd på objektet släpps.
  5. Om drivrutinen anropade ExAllocateCacheAwareRundownProtection tidigare bör den anropa ExFreeCacheAwareRundownProtection för att frigöra rundown-referensen.

För att återanvända en cachemedveten sammanställningsreferens, följ dessa steg:

  1. Efter att ha anropat ExWaitForRundownProtectionReleaseCacheAware anropar du ExRundownCompletedCacheAware för att ange att nedkörningen av det gamla objektet har avslutats.
  2. Anropa ExReInitializeRundownProtectionCacheAware för att initiera referensen igen när det associerade objektet har körts ned.
  3. Nu kan drivrutinen anropa ExAcquireRundownProtectionCacheAware igen.

En cachemedveten rundown-referens har fördelen av bättre prestanda och skalbarhet i specifika situationer, men den förbrukar mer minne än en vanlig rundown-referens. Det är viktigt att överväga denna kompromiss när du väljer mellan de två typerna av genomgångsreferenser.