Dela via


Allokera System-Space minne

Viktigt!

DDI:er för ExAllocatePool som beskrivs i det här avsnittet har föråldrats i Windows 10 version 2004 och har ersatts av ExAllocatePool2 och ExAllocatePool3. För mer information, se Uppdatering av inaktuella ExAllocatePool-anrop till ExAllocatePool2 och ExAllocatePool3.

Drivrutiner kan använda systemallokerat utrymme i sina enhetstillägg som globala lagringsområden för enhetsspecifik information. Drivrutiner kan bara använda kernelstacken för att skicka små mängder data till sina interna rutiner. Vissa drivrutiner måste allokera ytterligare, större mängder systemutrymmesminne, vanligtvis för I/O-buffertar.

Om du vill allokera I/O-buffertutrymme är de bästa rutinerna för minnesallokering MmAllocateNonCachedMemory, MmAllocateContiguousMemorySpecifyCache, AllocateCommonBuffer (om drivrutinens enhet använder buss-master-DMA eller en system-DMA-styrenhets autoinitieringsläge) eller ExAllocatePoolWithTag.

Icke-sidig pool blir vanligtvis fragmenterad när systemet körs, så en drivrutins DriverEntry rutin bör anropa dessa rutiner för att konfigurera eventuella långsiktiga I/O-buffertar som drivrutinen behöver. Var och en av dessa rutiner, förutom ExAllocatePoolWithTag, allokerar minne som är justerat på en processorspecifik gräns (bestäms av processorns datacachelinjestorlek) för att ge bästa prestanda.

Drivrutiner bör allokera I/O-buffertar så ekonomiskt som möjligt, eftersom icke-sidindelat poolminne är en begränsad systemresurs. Vanligtvis bör en drivrutin undvika att anropa dessa supportrutiner upprepade gånger för att begära allokeringar på mindre än PAGE_SIZE eftersom varje allokering som är mindre än PAGE_SIZE också levereras med ett poolhuvud som används för att hantera allokeringen internt.

Tips för att allokera drivrutinsbuffertutrymme ekonomiskt

Om du vill allokera I/O-buffertminne ekonomiskt bör du vara medveten om följande:

  • Varje anrop till MmAllocateNonCachedMemory eller MmAllocateContiguousMemorySpecifyCache returnerar alltid en fullständig multipel av systemets sidstorlek, av icke-sidigt systemutrymmesminne, oavsett storleken på den begärda allokeringen. Därför avrundas begäranden för mindre än en sida upp till en hel sida och eventuella återstående byte på sidan slösas bort. De är otillgängliga för drivrutinen som anropade funktionen och är oanvändbara för annan kod som körs i kärnläge.

  • Varje anrop till AllocateCommonBuffer använder minst ett adapterobjektmappningsregister, som mappar minst en byte och högst en sida. Mer information om mappningsregister och användning av vanliga buffertar finns i Adapter-objekt och DMA-.

Allokera minne med ExAllocatePoolWithTag

Drivrutiner kan också anropa ExAllocatePoolWithTagoch ange något av följande systemdefinierade POOL_TYPE värden för parametern PoolType:

  • PoolType = NonPagedPool för alla objekt eller resurser som inte är lagrade i ett enhetstillägg eller ett kontrollertillägg och som drivrutinen kan tillgå när den körs på IRQL > APC_LEVEL.

    För det här PoolType--värdet allokerar ExAllocatePoolWithTag mängden minne som begärs om den angivna NumberOfBytes- är mindre än eller lika med PAGE_SIZE. Annars slösas eventuella återstående byte på den senast allokerade sidan bort: otillgängliga för anroparen och oanvändbara av annan kod i kernelläge.

    På en x86 returnerar till exempel en allokeringsbegäran på 5 kilobyte (KB) två sidor med 4 KB. Den sista 3 kB på den andra sidan är inte tillgänglig för anroparen eller någon annan anropare. För att undvika att slösa bort icke-sidindelad pool bör drivrutinen allokera flera sidor effektivt. I det här fallet kan drivrutinen till exempel göra två allokeringar, en för PAGE_SIZE och en för 1 KB, för att allokera totalt 5 KB.

    Observera Från och med Windows Vista lägger systemet automatiskt till ytterligare minne så att två allokeringar inte behövs.

  • PoolType = PagedPool för minne som alltid är åtkommet på IRQL <= APC_LEVEL och inte finns i filsystemets skrivsökväg.

ExAllocatePoolWithTag returnerar en NULL- pekare om den inte kan allokera det begärda antalet byte. Drivrutiner bör alltid kontrollera den returnerade pekaren. Om värdet är NULL-ska DriverEntry- rutin (eller någon annan drivrutin som returnerar NTSTATUS-värden) returnera STATUS_INSUFFICIENT_RESOURCES eller hantera felvillkoret om möjligt.