NdisMAllocateSharedMemory 関数 (ndis.h)
注意事項
ARM および ARM64 プロセッサの場合、NDIS ドライバー ライターは、NDIS 散布/収集 DMA の代わりに WDF DMA または WDM DMA を使用することを強くお勧めします。
WDF DMA の詳細については、「 KMDF ドライバーでの DMA 操作の処理」を参照してください。
WDM DMA の詳細については、「 ドライバーの入出力の管理」の DMA 関連の子トピックを参照してください。
NdisMAllocateSharedMemory は、ホスト システムと DMA NIC の両方からメモリ範囲に同時にアクセスできるように、ホスト メモリ範囲を割り当ててマップします。
構文
void NdisMAllocateSharedMemory(
[in] NDIS_HANDLE MiniportAdapterHandle,
[in] ULONG Length,
[in] BOOLEAN Cached,
[out] PVOID *VirtualAddress,
[out] PNDIS_PHYSICAL_ADDRESS PhysicalAddress
);
パラメーター
[in] MiniportAdapterHandle
MiniportInitializeEx へのハンドル入力を指定します。
[in] Length
割り当てるバイト数を指定します。
[in] Cached
このパラメーターは無視されます (キャッシュされたメモリは常に x86 および x64 システムで使用されます)。
[out] VirtualAddress
この関数がミニポート ドライバーで使用する割り当ての基本仮想アドレスを返す呼び出し元から提供された変数へのポインター。 NdisMAllocateSharedMemory が呼び出し元を満たすことができない場合は、メモリが割り当てられていないことを示す NULL を返します。
[out] PhysicalAddress
呼び出し元が指定した変数へのポインター。この関数は、 VirtualAddress で返された変数に対応する NIC で使用するのに適した物理アドレスを返すか、 NULL を返します。
戻り値
なし
解説
NdisMAllocateSharedMemory は、ドライバーが共有メモリ ブロックにアクセスするために使用するマップされた仮想アドレス範囲と、NIC が使用する NDIS_PHYSICAL_ADDRESS型の範囲の両方を提供します。 PhysicalAddress で返される値は、システムによって二重にマップできます。 つまり、 PhysicalAddress と Length の値によって記述される "物理" アドレス範囲は、可能なすべてのプラットフォームでの割り当てに対してホストの物理アドレスと一致しないマップされた論理アドレスの範囲にすることができます。
NdisMAllocateSharedMemory は 、MiniportInitializeEx からのみ呼び出すことができます。 要求する割り当ての大きさは、NIC の機能と機能を把握しているドライバー ライターが、次のパフォーマンスとサイズのジレンマのトレードオフを決定する方法によって異なります。
-
ネットワーク トラフィックが多い期間、ミニポート ドライバーは、デバイスアクセス可能なデータ バッファーの共有メモリ領域が不足している場合、高い I/O スループットを維持できません。
たとえば、ミニポート ドライバーは、受信のフラッディングが NIC に入ったときにバインドされたプロトコル ドライバーからこのようなバッファーが返されるよりも高速に共有メモリ内の受信バッファーを示している可能性があります。 未処理の受信バッファーによって共有メモリ領域がすべて消費される場合、ミニポート ドライバーは、受信バッファーに使用できる共有メモリ領域が存在するまで、NIC の受信割り込みを無効にする必要がある場合があります。
- 一方、最大転送需要を予測するために選択された Length を指定して NdisMAllocateSharedMemory を呼び出すと、非常に高い I/O 需要のまれな期間を除き、ドライバーのイメージが大きくなり、そのリソース使用量は非常に不経済になります。 さらに、システム メモリが不足している場合、 NdisMAllocateSharedMemory はドライバーにこのような大きなブロックを与えない可能性があり、ドライバーの初期化に失敗する必要があります。
NdisMAllocateSharedMemory および NdisMAllocateSharedMemoryAsyncEx は、仮想アドレスを使用するドライバーと、対応する論理アドレスを使用する NIC の間で共有されるホスト メモリを割り当てるために呼び出すことができる唯一の NdisXxx 関数です。
ミニポート ドライバーは、DMA 中にキャッシュラインのティアリングを防ぐために、ホストデータキャッシュライン境界の不可欠な共有キャッシュメモリから割り当てるバッファーを配置する必要があります。 キャッシュラインのティアリングにより、ドライバーのデータ整合性の問題が発生したり、データの整合性を維持するために過剰なデータ キャッシュフラッシュが必要になり、ドライバー (およびシステム) の I/O パフォーマンスが低下したりする可能性があります。 MiniportInitializeEx は NdisMGetDmaAlignment を呼び出して、ドライバーが割り当てられた共有メモリの範囲内で設定するデバイスアクセス可能なバッファーの現在のプラットフォームの配置境界を決定できます。
ミニポート ドライバーは、割り当てることができる共有メモリの量に制限を設定する必要があります。 この制限はドライバー固有であり、ドライバーがバッファーを使い果たさないように十分に高くする必要があります。 過剰に高い制限を設定しないでください。これにより、共有メモリが無駄に消費され、システム のパフォーマンスが低下する可能性があります。
また、ドライバー ライターがマルチプロセッサ マシンに大きな共有メモリ ブロックを割り当てることを決定した場合、SMP マシンがワークステーションよりも NIC のネットワーク転送要求が高いネットワーク サーバーである可能性が高いと判断した場合、MiniportInitializeEx は NdisMAllocateSharedMemory を呼び出す前に NdisSystemProcessorCount を呼び出す可能性もあります。
NdisMAllocateSharedMemory の呼び出しが失敗した場合、MiniportInitializeEx は小さい割り当てを要求して再度呼び出すことができます。 ただし、 MiniportInitializeEx が NIC に十分な共有メモリを割り当てることができない場合は、既に割り当てられているすべてのリソースを解放し、初期化に失敗する必要があります。
ミニポート ドライバーは、その後で を受信を示す場合 NdisMIndicateReceiveNetBufferLists では、共有メモリ ブロック内の NIC の受信バッファーをマップするバッファー プールからいくつかのバッファー記述子を割り当てる必要があります。
割り当てられたメモリがキャッシュされるため、転送時にフラッシュする必要がある場合、ミニポート ドライバーは NdisAllocateMdl を呼び出して、共有メモリ範囲のNDIS_BUFFER型記述子を割り当てる必要があります。 ミニポート ドライバーは、このようなフラッシュを実行するには、このバッファー記述子で KeFlushIoBuffers を呼び出す必要があります。
ミニポート ドライバーがを呼び出す場合 NdisMAllocateSharedMemoryAsyncEx または NdisMAllocateSharedMemory は、NIC が削除されたとき、つまり、MiniportHaltEx 関数が呼び出されたときに、NdisMFreeSharedMemory への 1 つ以上の呼び出しで未処理のすべての割り当てを解放する必要があります。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | NDIS 6.0 以降でサポートされています。 |
対象プラットフォーム | ユニバーサル |
Header | ndis.h (Ndis.h を含む) |
Library | Ndis.lib |
IRQL | PASSIVE_LEVEL |