Zuweisung von System-Space Arbeitsspeicher

Wichtig

Die in diesem Thema beschriebenen ExAllocatePool-DDIs sind in Windows 10 Version 2004 veraltet und wurden durch ExAllocatePool2 und ExAllocatePool3 ersetzt. Weitere Informationen finden Sie unter Aktualisieren veralteter ExAllocatePool-Aufrufe von ExAllocatePool2 und ExAllocatePool3.

Treiber können den vom System zugewiesenen Speicherplatz in ihren Geräteerweiterungen als globale Speicherbereiche für gerätespezifische Informationen verwenden. Treiber können nur den Kernelstapel verwenden, um kleine Datenmengen an ihre internen Routinen zu übergeben. Einige Treiber müssen zusätzliche, größere Mengen an Systemspeicher zuordnen, in der Regel für E/A-Puffer.

Zum Zuordnen des E/A-Pufferspeichers sind die besten Speicherbelegungsroutinen MmAllocateNonCachedMemory, MmAllocateContiguousMemorySpecifyCache, AllocateCommonBuffer (wenn das Gerät des Treibers bus-master DMA oder den Automatischinitialisierungsmodus eines System-DMA-Controllers verwendet) oder ExAllocatePoolWithTag.

Nicht auslagerter Pool wird in der Regel fragmentiert, wenn das System ausgeführt wird. Daher sollte die DriverEntry-Routine eines Treibers diese Routinen aufrufen, um alle langfristigen E/A-Puffer einzurichten, die der Treiber benötigt. Jede dieser Routinen, mit Ausnahme von ExAllocatePoolWithTag, weist Arbeitsspeicher zu, der an einer prozessorspezifischen Grenze (bestimmt durch die Größe der Datencachezeile des Prozessors) ausgerichtet ist, um eine optimale Leistung zu erzielen.

Treiber sollten E/A-Puffer so wirtschaftlich wie möglich zuordnen, da der nicht auslagerte Poolspeicher eine begrenzte Systemressource ist. In der Regel sollte ein Treiber vermeiden, diese Supportroutinen wiederholt zu aufrufen, um Zuordnungen von weniger als PAGE_SIZE anzufordern, da jede Zuordnung, die kleiner als PAGE_SIZE ist, auch einen Poolheader enthält, der zum internen Verwalten der Zuordnung verwendet wird.

Tipps zum zuweisen des Treiberpufferplatzes wirtschaftlich

Beachten Sie Folgendes, um E/A-Pufferspeicher wirtschaftlich zuzuordnen:

  • Jeder Aufruf von MmAllocateNonCachedMemory oder MmAllocateContiguousMemorySpecifyCache gibt immer ein vollständiges Vielfaches der Seitengröße des Systems zurück, des nicht ausgelagerten Systemspeicherspeichers, unabhängig von der Größe der angeforderten Zuordnung. Daher werden Anforderungen für weniger als eine Seite auf eine ganze Seite aufgerundet, und alle restlichen Bytes auf der Seite werden verschwendet. Auf sie kann der Treiber, der die Funktion aufgerufen hat, nicht zugreifen und für anderen Kernelmoduscode nicht verwendet werden.

  • Jeder Aufruf von AllocateCommonBuffer verwendet mindestens ein Adapterobjektzuordnungsregister, das mindestens ein Byte und höchstens eine Seite zuordnet. Weitere Informationen zu Kartenregistern und zur Verwendung gängiger Puffer finden Sie unter Adapterobjekte und DMA.

Zuweisen von Arbeitsspeicher mit ExAllocatePoolWithTag

Treiber können auch ExAllocatePoolWithTag aufrufen und einen der folgenden systemdefinierte POOL_TYPE-Werte für den PoolType-Parameter angeben:

  • PoolType = NonPagedPool für alle Objekte oder Ressourcen, die nicht in einer Geräteerweiterung oder Controllererweiterung gespeichert sind, auf die der Treiber möglicherweise zugreift, während er am IRQL-APC_LEVEL > ausgeführt wird.

    Für diesen PoolType-Wert weist ExAllocatePoolWithTag die angeforderte Arbeitsspeichermenge zu, wenn der angegebene NumberOfBytes kleiner oder gleich PAGE_SIZE ist. Andernfalls werden alle restlichen Bytes auf der zuletzt zugeordneten Seite verschwendet: Der Aufrufer kann nicht darauf zugreifen und kann von anderen Kernelmoduscode nicht verwendet werden.

    Beispielsweise gibt eine Zuordnungsanforderung von 5 Kb (KB) auf einem x86-Objekt zwei Seiten mit einer Größe von 4 KB zurück. Die letzten 3 KB der zweiten Seite sind für den Aufrufer oder einen anderen Aufrufer nicht verfügbar. Um zu vermeiden, dass nicht ausseitiger Pool gelöscht wird, sollte der Treiber mehrere Seiten effizient zuordnen. In diesem Fall könnte der Treiber beispielsweise zwei Zuordnungen vornehmen, eine für PAGE_SIZE und die andere für 1 KB, um insgesamt 5 KB zuzuweisen.

    Hinweis Ab Windows Vista fügt das System automatisch den zusätzlichen Arbeitsspeicher hinzu, sodass zwei Zuordnungen unnötig sind.

  • PoolType = PagedPool für Arbeitsspeicher, auf den immer unter IRQL <= APC_LEVEL zugegriffen wird und sich nicht im Schreibpfad des Dateisystems befindet.

ExAllocatePoolWithTag gibt einen NULL-Zeiger zurück, wenn die angeforderte Anzahl von Bytes nicht zugeordnet werden kann. Treiber sollten immer den zurückgegebenen Zeiger überprüfen. Wenn der Wert NULL ist, sollte die DriverEntry-Routine (oder jede andere Treiberroutine, die NTSTATUS-Werte zurückgibt) nach Möglichkeit STATUS_INSUFFICIENT_RESOURCES zurückgeben oder die Fehlerbedingung behandeln.