NdisMAllocateSharedMemory-Funktion (ndis.h)

Achtung

Für ARM- und ARM64-Prozessoren wird dringend empfohlen, dass NDIS-Treiberautoren WDF DMA oder WDM DMA anstelle von NDIS Scatter/Gather DMA verwenden.

Weitere Informationen zu WDF DMA finden Sie unter Behandeln von DMA-Vorgängen in KMDF-Treibern.

Weitere Informationen zu WDM DMA finden Sie in den DMA-bezogenen untergeordneten Themen unter Verwalten von Eingabe/Ausgabe für Treiber.

NdisMAllocateSharedMemory ordnet einen Hostspeicherbereich zu und ordnet ihn zu, sodass gleichzeitig auf den Speicherbereich sowohl vom Hostsystem als auch von einer DMA-NIC aus zugegriffen werden kann.

Syntax

void NdisMAllocateSharedMemory(
  [in]  NDIS_HANDLE            MiniportAdapterHandle,
  [in]  ULONG                  Length,
  [in]  BOOLEAN                Cached,
  [out] PVOID                  *VirtualAddress,
  [out] PNDIS_PHYSICAL_ADDRESS PhysicalAddress
);

Parameter

[in] MiniportAdapterHandle

Gibt die Handleeingabe für MiniportInitializeEx an.

[in] Length

Legt die Anzahl der zuzuweisenden Bytes fest.

[in] Cached

Dieser Parameter wird ignoriert (zwischengespeicherter Arbeitsspeicher wird immer auf x86- und x64-Systemen verwendet).

[out] VirtualAddress

Zeiger auf eine vom Aufrufer bereitgestellte Variable, in der diese Funktion die virtuelle Basisadresse der Zuordnung zur Verwendung durch den Miniporttreiber zurückgibt. Wenn NdisMAllocateSharedMemory seinen Aufrufer nicht erfüllen kann, wird NULL zurückgegeben, um anzugeben, dass kein Arbeitsspeicher zugewiesen wurde.

[out] PhysicalAddress

Zeiger auf eine vom Aufrufer bereitgestellte Variable, in der diese Funktion eine physische Adresse zurückgibt, die für die Verwendung durch die NIC geeignet ist, die der von VirtualAddress zurückgegebenen entspricht, oder null zurückgibt.

Rückgabewert

Keine

Bemerkungen

Hinweis Ein Miniporttreiber muss bereits NdisMRegisterScatterGatherDma oder NdisMRegisterDmaChannel aufgerufen haben, um vor dem Aufrufen von NdisMAllocateSharedMemory einen Punkt/Gather-DMA-Kanal zu initialisieren.
 
Microsoft Windows Server 2003, Windows XP Service Pack 1 und höhere Versionen von Windows ermöglichen sowohl Bus-master DMA-NICs als auch untergeordnete DMA-NICs das Aufrufen von NdisMAllocateSharedMemory. Bei früheren Versionen können nur Bus-master DMA-NICs NdisMAllocateSharedMemory aufrufen. Wenn MiniportInitializeEx in diesen früheren Releases nicht angegeben hat, dass die NIC ein Bus master, wenn sie NdisMSetMiniportAttributes aufgerufen hat, gibt NdisMAllocateSharedMemory einfach die Steuerung zurück, ohne zu versuchen, eine Zuordnung vorzunehmen.

NdisMAllocateSharedMemory stellt sowohl den zugeordneten virtuellen Adressbereich bereit, den der Treiber für den Zugriff auf den freigegebenen Speicherblock verwendet, als auch den von der NIC verwendeten NDIS_PHYSICAL_ADDRESS-Typbereich. Ein wert, der an PhysicalAddress zurückgegeben wird, kann vom System doppelt zugeordnet werden. Das heißt, ein "physischer" Adressbereich, der durch den Wert unter PhysicalAddress und Length beschrieben wird, kann ein Bereich zugeordneter logischer Adressen sein, die nicht mit den physischen Hostadressen für die Zuordnung auf jeder möglichen Plattform übereinstimmen.

NdisMAllocateSharedMemory kann nur über MiniportInitializeEx aufgerufen werden. Wie groß eine zu fordernde Zuordnung ist, hängt davon ab, wie der Treiberschreiber, der die Funktionen und Features der NIC kennt, entscheidet, den Kompromiss zwischen dem folgenden Leistungs- und Größendilemma zu treffen:

  • In Zeiten mit hohem Netzwerkdatenverkehr kann ein Miniporttreiber keinen hohen E/A-Durchsatz aufrechterhalten, wenn er nur wenig freigegebenen Speicherplatz für auf gerätezugängliche Datenpuffer hat.

    Beispielsweise könnte der Miniporttreiber Empfangspuffer im freigegebenen Speicher angeben, die schneller als solche Puffer von gebundenen Protokolltreibern zurückgegeben werden, wenn eine Flut von Empfangsvorgängen in eine NIC eingeht. Wenn der gesamte freigegebene Speicherplatz von ausstehenden Empfangspuffern belegt wird, muss der Miniporttreiber möglicherweise Empfangsunterbrechungen auf einer NIC deaktivieren, bis ein freigegebener Speicherplatz für Empfangspuffer verfügbar ist.

  • Andererseits macht der Aufruf von NdisMAllocateSharedMemory mit einer Länge , die ausgewählt wurde, um einen gewissen maximalen Übertragungsbedarf zu erwarten, das Image des Fahrers und seine Ressourcennutzung ziemlich unwirtschaftlich, mit Ausnahme seltener Zeiträume mit sehr hoher E/A-Nachfrage. Darüber hinaus gibt NdisMAllocateSharedMemory dem Treiber möglicherweise keinen so großen Block, wenn nicht genügend Systemspeicher verfügbar ist, wodurch der Treiber zu einem Fehler bei der Initialisierung gezwungen wird.
Ein Miniporttreiber, der einen Die MiniportSharedMemoryAllocateComplete-Funktion hat erheblich mehr Flexibilität bei der Lösung des vorherigen Leistungs- und Größenkonflikts. MiniportInitializeEx sollte nur genügend freigegebenen Arbeitsspeicher mit NdisMAllocateSharedMemory zuweisen, um einen moderaten Bedarf an Netzwerkübertragungsvorgängen über die NIC zu erhalten, wenn der Treiber über eine MiniportSharedMemoryAllocateComplete-Funktion verfügt. Ein solcher Miniporttreiber kann aufrufen NdisMAllocateSharedMemoryAsyncEx dynamisch, um mehr gemeinsam genutzten Arbeitsspeicher in Zeiten mit einem höheren Übertragungsbedarf für eine NIC zuzuweisen. Wenn die hohe Nachfrage nach Übertragungen nachlässt, ruft ein solcher Treiber NdisMFreeSharedMemory auf, um den von ihm zugewiesenen zusätzlichen Arbeitsspeicher freizugeben. Beachten Sie, dass nur Bus-master DMA-NICs NdisMAllocateSharedMemoryAsyncEx aufrufen und MiniportSharedMemoryAllocateComplete exportieren können. Diese Funktionalität wird für untergeordnete DMA-NICs nicht unterstützt.

NdisMAllocateSharedMemory und NdisMAllocateSharedMemoryAsyncEx sind die einzigen NdisXxx-Funktionen , die aufgerufen werden können, um Hostspeicher zuzuweisen, der zwischen dem Treiber gemeinsam genutzt wird, der virtuelle Adressen verwendet, und einer NIC, die die entsprechenden logischen Adressen verwendet.

Ein Miniporttreiber sollte die Puffer, die er aus freigegebenem zwischengespeichertem Speicher ordnet, an einem Integral der Hostdaten-Cache-Line-Grenze ausrichten, um das Löschen von Cachelinien während des DMA zu verhindern. Das Löschen von Cachelinien kann Zu Problemen mit der Datenintegrität im Treiber führen oder die E/A-Leistung des Treibers (und der System) beeinträchtigen, da ein übermäßiges Leeren des Datencaches erforderlich ist, um die Datenintegrität aufrechtzuerhalten. MiniportInitializeEx kann NdisMGetDmaAlignment aufrufen, um die Ausrichtungsgrenze auf der aktuellen Plattform für pufferbare Geräte zu bestimmen, die der Treiber in einem zugeordneten Bereich gemeinsam genutzten Arbeitsspeichers einrichten wird.

Ein Miniporttreiber sollte einen Grenzwert für die Zuweisung von gemeinsam genutztem Arbeitsspeicher festlegen. Dieser Grenzwert ist treiberspezifisch und sollte hoch genug sein, damit dem Treiber nicht die Puffer ausgehen. Legen Sie keinen grenzwert fest, der übermäßig hoch ist, da dies zu einem verschwenderlichen Verbrauch von gemeinsam genutztem Arbeitsspeicher führen kann, der die Systemleistung beeinträchtigen könnte.

MiniportInitializeEx kann auch NdisSystemProcessorCount aufrufen, bevor NdisMAllocateSharedMemory aufgerufen wird, wenn sich der Treiberautor entscheidet, einen größeren freigegebenen Speicherblock auf Multiprozessorcomputern zuzuweisen, wobei davon ausgegangen wird, dass es sich bei einem SMP-Computer wahrscheinlich um einen Netzwerkserver handelt, der höhere Anforderungen an die Netzwerkkarte als eine Arbeitsstation hat.

Wenn der Aufruf von NdisMAllocateSharedMemory fehlschlägt, kann MiniportInitializeEx erneut aufrufen und eine kleinere Zuordnung anfordern. Wenn MiniportInitializeEx jedoch nicht genügend freigegebenen Arbeitsspeicher für die NIC zuweisen kann, muss es alle ressourcen freigeben, die bereits zugewiesen wurden, und die Initialisierung schlägt fehl.

Wenn der Miniporttreiber anschließend mit "empfängt" angibt NdisMIndicateReceiveNetBufferLists muss eine Reihe von Pufferdeskriptoren aus dem Pufferpool zuordnen, die die Empfangspuffer der Netzwerkkarte im Block des freigegebenen Arbeitsspeichers zuordnen.

Wenn der zugeordnete Arbeitsspeicher zwischengespeichert wird und daher bei Übertragungen geleert werden muss, muss der Miniporttreiber NdisAllocateMdl aufrufen, um einen NDIS_BUFFER-Typdeskriptor für den freigegebenen Speicherbereich zuzuweisen. Der Miniporttreiber muss KeFlushIoBuffers mit diesem Pufferdeskriptor aufrufen, um eine solche Leerung auszuführen.

Wenn ein Miniporttreiber aufruft NdisMAllocateSharedMemoryAsyncEx oder NdisMAllocateSharedMemory muss alle ausstehenden Zuordnungen mit einem oder mehreren Aufrufen von NdisMFreeSharedMemory freigeben, wenn eine NIC entfernt wird, d. h. wenn die MiniportHaltEx-Funktion aufgerufen wird.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Unterstützt in NDIS 6.0 und höher.
Zielplattform Universell
Header ndis.h (include Ndis.h)
Bibliothek Ndis.lib
IRQL PASSIVE_LEVEL

Weitere Informationen

KeFlushIoBuffers

MiniportHaltEx

MiniportInitializeEx

MiniportSharedMemoryAllocateComplete

NdisAllocateMdl

NdisMAllocateNetBufferSGList

NdisMAllocateSharedMemoryAsyncEx

NdisMFreeSharedMemory

NdisMGetDmaAlignment

NdisMIndicateReceiveNetBufferLists

NdisMSetMiniportAttributes

NdisSystemProcessorCount