MmAllocatePagesForMdlEx 関数 (wdm.h)

MmAllocatePagesForMdlEx ルーチンは、非ページの物理メモリ ページを MDL に割り当てます。

MmAllocatePagesForMdl の代わりに、このルーチンを使用します。

構文

PMDL MmAllocatePagesForMdlEx(
  [in] PHYSICAL_ADDRESS    LowAddress,
  [in] PHYSICAL_ADDRESS    HighAddress,
  [in] PHYSICAL_ADDRESS    SkipBytes,
  [in] SIZE_T              TotalBytes,
  [in] MEMORY_CACHING_TYPE CacheType,
  [in] ULONG               Flags
);

パラメーター

[in] LowAddress

割り当てられたページを取得できる最初のアドレス範囲の先頭の物理アドレスを指定します。 MmAllocatePagesForMdlEx が最初のアドレス範囲に要求されたバイト数を割り当てることができない場合は、追加のアドレス範囲を反復処理してより多くのページを取得します。 各イテレーションで、 MmAllocatePagesForMdlEx は、前の開始アドレスに SkipBytes の値を追加して、次のアドレス範囲の開始を取得します。

[in] HighAddress

割り当てられたページの取得元となる最初のアドレス範囲の末尾の物理アドレスを指定します。

[in] SkipBytes

割り当てられたページの取得元となる前のアドレス範囲の先頭からスキップするバイト数を指定します。 SkipBytes は、仮想メモリ ページ サイズの整数倍数 (バイト単位) である必要があります。

[in] TotalBytes

MDL に割り当てる合計バイト数を指定します。

[in] CacheType

MEMORY_CACHING_TYPE値を指定します。これは、要求されたメモリに対して許可されるキャッシュの種類を示します。

[in] Flags

この操作のフラグを指定します。 このパラメーターを 0 に設定するか、次の 1 つ以上の MM_ALLOCATE_XXX フラグ ビットのビットごとの OR に設定します。

前の一覧の最後の 4 つの項目は、Windows 7 以降のバージョンの Windows でのみサポートされています。

意味
MM_DONT_ZERO_ALLOCATION 0x00000001 割り当てられたページにゼロを入力しないでください。 既定では、MmAllocatePagesForMdlEx は割り当てるページをゼロにします。 この操作をスキップすると、MmAllocatePagesForMdlEx 呼び出しのパフォーマンスが向上する可能性があります。 ただし、割り当てられたページをユーザー モード プログラムに公開しない場合、または割り当てられたページをユーザー モード プログラムに公開する前に常にページの元の内容を上書きする場合を除き、このフラグを使用しないでください。
MM_ALLOCATE_FROM_LOCAL_NODE_ONLY 0x00000002 理想的なノードからのみページを割り当てます。 このフラグは、非均一メモリ アクセス (NUMA) アーキテクチャを持つマルチプロセッサ システムにのみ適用されます。 Windows Vista 以降では、このフラグは、現在のスレッドの理想的なノードからすべてのページを割り当てる必要があることを示します。 他のノードからページを割り当てる必要はありません。 Windows Vista より前のバージョンの Windows では、このフラグは、すべてのページをローカル ノードから割り当てる必要があることを示します。つまり、現在のプロセッサが属しているノードから。 NUMA マルチプロセッサ システムの詳細については、「 NUMA サポート 」を参照してください。
MM_ALLOCATE_FULLY_REQUIRED 0x00000004 完全な割り当てが必要です。 Windows 7 以降では、このフラグは、要求されたすべてのページを割り当てることができない場合に NULL を返すために MmAllocatePagesForMdlEx を必要とします。 ルーチンは、要求された割り当て全体が正常に取得された場合にのみ、NULL 以外の値を返します。 このフラグを使用すると、呼び出し元が完全な割り当てを必要とする場合に、メモリ マネージャーがより効率的に割り当てを実行できます。
MM_ALLOCATE_NO_WAIT 0x00000008 待つ必要はありません。 Windows 7 以降では、このフラグは、MmAllocatePagesForMdlEx 呼び出しで呼び出し元スレッドをブロックしてはならないことを示します。 通常、呼び出し元は IRQL < DISPATCH_LEVELで実行されているカーネル モード ドライバーですが、その実行をブロックすることはできません。 たとえば、ドライバーがページング操作や電源管理操作を支援している可能性があります。 このフラグが設定されているかどうかに関係なく、MmAllocatePagesForMdlEx は IRQL = DISPATCH_LEVELで実行されている呼び出し元をブロックしません。
MM_ALLOCATE_PREFER_CONTIGUOUS 0x00000010 割り当ては、システム メモリの断片化を最小限に抑える方法で実行されます。 Windows 7 以降では、このフラグは、呼び出し元が他の呼び出し元がより連続するメモリを使用できるように、物理メモリの断片化を回避することを望んでいることを示します。 割り当てられたページは、大量の連続したメモリが使用可能な場合でも、物理的に連続している (通常は連続していない) とは限りません。 連続したメモリを必要とする呼び出し元は、MM_ALLOCATE_PREFER_CONTIGUOUSではなくMM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKSを指定する必要があります。
MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS 0x00000020 連続するメモリが必要です。 Windows 7 以降では、このフラグは、要求されたページを物理メモリの連続したブロックとして割り当てる必要があることを示します。 SkipBytes パラメーターが 0 の場合、MmAllocatePagesForMdlEx は成功して 1 つの連続したブロックを返すか、失敗して NULL を返します。 部分割り当ては返されません。 SkipBytes = 0 の場合、割り当てられたページは LowAddress パラメーターと HighAddress パラメーターで指定されたアドレス範囲の要件を満たしますが、ページには特別な配置制限はありません。 SkipBytes が 0 以外の場合、SkipBytes は 2 の累乗であり、PAGE_SIZE以上である必要があり、TotalBytes パラメーターの値は SkipBytes の倍数である必要があります。 この場合、返される MDL には、連続するページの複数のブロックを含めることができます。 つまり、各ブロックは内部的に連続していますが、ブロックが互いに連続しているとは限りません。 連続するページの各ブロックは、正確に SkipBytes 長く、SkipBytes 境界に配置されていることが保証されます。 部分割り当ては、SkipBytes が 0 以外の場合に発生する可能性がありますが、部分割り当ての各連続したブロックは SkipBytes 長であることが保証されます。
MM_ALLOCATE_FAST_LARGE_PAGES 0x00000040 Windows 8以降、このフラグは、オペレーティング システムの大きなページ キャッシュからの割り当てを満たす必要があることを指定します。 キャッシュが空の場合、割り当ては失敗します。  MM_ALLOCATE_FAST_LARGE_PAGESが指定されていない場合、 MmAllocatePagesForMdlEx はキャッシュされた大きなページが使用可能な場合に使用します。 キャッシュが使い果たされると、 MmAllocatePagesForMdlEx は 追加の大きなページの構築を試みますが、時間がかかる場合があります。 MM_ALLOCATE_FAST_LARGE_PAGESは、MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS フラグと共に使用する必要があります。 SkipBytes パラメーターは、大きなページ サイズの倍数に設定する必要があります。
MM_ALLOCATE_AND_HOT_REMOVE 0x00000100 Windows 10以降、このフラグにより、割り当てられたページが Windows によって管理される物理メモリのプールから削除されます。 MM_ALLOCATE_AND_HOT_REMOVEをMM_ALLOCATE_FULLY_REQUIREDと共に指定することはできません。 MM_ALLOCATE_AND_HOT_REMOVEを指定した場合、呼び出し元は IRQL = PASSIVE_LEVELで実行されている必要があります。

戻り値

MmAllocatePagesForMdlEx は 、次のいずれかを返します。

リターン コード 説明
MDL ポインター NULL 以外の戻り値は、指定されたアドレス範囲内の物理ページのセットを記述する MDL へのポインターです。 要求されたバイト数が使用できない場合、MDL は使用可能な量の物理メモリを記述します。
NULL 指定したアドレス範囲に物理メモリ ページが使用できないか、MDL 自体に十分なメモリ プールがないことを示します。

注釈

既定では、 MmAllocatePagesForMdlEx から返される物理メモリ ページは連続したページではありません。 Windows 7 以降では、呼び出し元は Flags パラメーターでフラグ ビットをMM_ALLOCATE_PREFER_CONTIGUOUSまたはMM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS設定することで、このルーチンの既定の動作をオーバーライドできます。

MmAllocatePagesForMdlEx は、対応する仮想アドレスを必要としないカーネル モード ドライバー (つまり、物理ページが必要であり、物理的に連続している必要はありません) と、デバイスの物理メモリが特定の物理アドレス範囲 (たとえば、AGP グラフィックス カード) に割り当てられている場合に大幅なパフォーマンス向上を実現できるカーネル モード ドライバー用に設計されています。

MmAllocatePagesForMdlEx は、要求された範囲で現在使用できる物理メモリの量に応じて、要求されたメモリよりも少ないメモリを記述する MDL を返す場合があります。 また、メモリが割り当てられていない場合、ルーチンは NULL を 返す場合もあります。 呼び出し元は、MDL に実際に割り当てられているメモリの量をチェックする必要があります。

呼び出し元は MmFreePagesFromMdl を 使用して、 MmAllocatePagesForMdlEx によって作成された MDL によって記述されたメモリ ページを解放する必要があります。 MmFreePagesFromMdl を呼び出した後、呼び出し元は ExFreePool を呼び出して、MDL 構造体に割り当てられているメモリを解放する必要もあります。

既定では、 MmAllocatePagesForMdlEx は割り当てるページにゼロを設定します。 呼び出し元は、MM_DONT_ZERO_ALLOCATION フラグを指定して、この既定値をオーバーライドし、パフォーマンスを向上させることができます。

MM_DONT_ZERO_ALLOCATION フラグを指定した場合、 MmAllocatePagesForMdlEx によって 割り当てられるメモリは初期化されません。 ドライバーがユーザー モード ソフトウェアにメモリを表示する場合 (特権の可能性のあるコンテンツのリークを回避するため) カーネル モード ドライバーは、最初にこのメモリをゼロにする必要があります。 このフラグの詳細については、「 MM_ALLOCATE_XXX」を参照してください。

MmAllocatePagesForMdlEx が 1 回の呼び出しで割り当てることができるメモリの最大量は (4 ギガバイト - PAGE_SIZE) です。 ルーチンは、十分なページが使用可能な場合にのみ、この量の割り当て要求を満たすことができます。

MmAllocatePagesForMdlEx は IRQL <= APC_LEVELで実行されます。 MmAllocatePagesForMdlEx の呼び出し元は、DISPATCH_LEVELで使用できます。 ただし、APC_LEVEL 以下で を呼び出すことで、ドライバーのパフォーマンスを向上させることができます。

要件

要件
対象プラットフォーム ユニバーサル
Header wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む)
Library NtosKrnl.lib
[DLL] NtosKrnl.exe
IRQL 「解説」を参照してください。
DDI コンプライアンス規則 IrqlMmApcLte(wdm)

こちらもご覧ください

ExFreePool

MEMORY_CACHING_TYPE

MmAllocatePagesForMdl

MmFreePagesFromMdl

MmMapLockedPages