MmAllocateNodePagesForMdlEx 函式 (wdm.h)

MmAllocateNodePagesForMdlEx 例程會從理想的節點配置非分頁的實體記憶體,並配置 MDL 結構來描述此記憶體。

語法

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

參數

[in] LowAddress

第一個位址範圍的實體位址,其中配置的頁面可以來自該位址範圍。 如果 MmAllocateNodePagesForMdlEx 無法在第一個位址範圍中配置要求的位元組數目,例程會逐一查看其他地址範圍以取得更多頁面。 在每個反覆專案中, MmAllocateNodePagesForMdlEx 會將 SkipBytes 的值新增至先前的起始位址,以計算下一個位址範圍的開始。

[in] HighAddress

配置頁面可以來自之第一個位址範圍結尾的實體位址。

[in] SkipBytes

要從前一個位址範圍的開頭略過位元組數目,這些位址範圍是配置的頁面可以來自該位址範圍。 SkipBytes 必須是虛擬記憶體頁面大小的整數倍數,以位元組為單位。

[in] TotalBytes

要配置給 MDL 的位元組總數。

[in] CacheType

MEMORY_CACHING_TYPE值,表示要求記憶體允許的快取類型。

[in] IdealNode

理想的節點編號。 如果多處理器系統包含 N 個節點,則有效的節點編號範圍介於 0 到 N-1 之間。 您的驅動程式可以呼叫 KeQueryHighestNodeNumber 例程,以取得最高的節點編號。 單處理器或非 NUMA 多處理器系統只有一個節點節點 0,要從中配置記憶體。 若為 NUMA 多處理器系統,則會盡可能從理想的節點進行配置。 如果理想的節點中沒有足夠的記憶體來滿足配置要求,而且呼叫端未設定MM_ALLOCATE_FROM_LOCAL_NODE_ONLY旗標, MmAllocateNodePagesForMdlEx 會嘗試從其他節點配置記憶體。

[in] Flags

這項作業的旗標。 將此參數設定為零或下列一或多個旗標位的位 OR:

  • MM_DONT_ZERO_ALLOCATION

  • MM_ALLOCATE_FROM_LOCAL_NODE_ONLY

  • MM_ALLOCATE_FULLY_REQUIRED

  • MM_ALLOCATE_NO_WAIT

  • MM_ALLOCATE_PREFER_CONTIGUOUS

  • MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS

  • MM_ALLOCATE_AND_HOT_REMOVE

如需這些旗標的詳細資訊,請參閱 MM_ALLOCATE_XXX

傳回值

MmAllocateNodePagesForMdlEx 會在成功時傳回 MDL 結構的指標。 否則,如果例程無法配置任何記憶體,則例程會傳回 NULL

NULL 的傳回值表示指定的位址範圍中沒有可用的物理記憶體分頁,或沒有足夠的記憶體集區可用來配置 MDL 結構。

如果例程成功配置要求記憶體的一些但並非全部,MDL 會描述例程能夠配置多少物理記憶體。

備註

在非統一記憶體存取 (NUMA) 多處理器系統中,呼叫端可以指定要從中配置記憶體的理想節點。 節點是處理器的集合,可共用對記憶體區域的快速存取。 在非 NUMA 多處理器或單一處理器系統中, MmAllocateNodePagesForMdlEx 會將所有記憶體視為屬於單一節點,並從這個節點配置記憶體。

根據預設, MmAllocateNodePagesForMdlEx 傳回的實體記憶體頁面不是連續的頁面。 呼叫端可以在 Flags 參數中設定MM_ALLOCATE_PREFER_CONTIGUOUS或MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS旗標位,以覆寫此例程的預設行為。

MmAllocateNodePagesForMdlEx 不會將配置的實體記憶體對應至虛擬記憶體。 如有必要,呼叫端可以呼叫 MmMapLockedPagesSpecifyCache 之類的例程,以對應 MDL 所描述的實體記憶體頁面。

MmAllocateNodePagesForMdlEx 是專為不需要對應虛擬位址的內核模式驅動程式所設計, (也就是說,它們需要實體頁面,而且不需要實體連續) ,而且對於核心模式驅動程式,如果裝置的實體記憶體配置在特定實體位址範圍中,可以大幅提升效能 (,例如, AGP 圖形) 。

根據要求範圍中目前可用的物理內存量而定, MmAllocateNodePagesForMdlEx 可能會傳回描述記憶體少於要求的 MDL。 如果未配置任何記憶體,例程也可能傳回 NULL 。 呼叫端應該檢查實際配置的記憶體數量,如 MDL 所述。

呼叫端必須使用 MmFreePagesFromMdl 釋放 由 MmAllocateNodePagesForMdlEx 所建立之 MDL 所描述的記憶體頁面。 呼叫 MmFreePagesFromMdl 之後,呼叫端也必須呼叫 ExFreePool ,以釋放為 MDL 結構配置的記憶體。

根據預設, MmAllocateNodePagesForMdlEx 會填滿配置零的頁面。 呼叫端可以指定MM_DONT_ZERO_ALLOCATION旗標來覆寫此預設值,並可能改善效能。

如果您指定MM_DONT_ZERO_ALLOCATION旗標, MmAllocateNodePagesForMdlEx 配置的記憶體不會初始化。 如果驅動程式要讓使用者模式軟體看到記憶體,則核心模式驅動程序必須先將這個記憶體零 (,以避免) 洩漏潛在的特殊許可權內容。 如需此旗標的詳細資訊,請參閱 MM_ALLOCATE_XXX

MmAllocateNodePagesForMdlEx 可以在單一呼叫中配置的記憶體數量上限為 (4 GB - PAGE_SIZE) 。 只有在有足夠的頁面可用時,例程才能滿足此數量的配置要求。

MmAllocateNodePagesForMdlEx 會在 IRQL <= APC_LEVEL執行。 如有必要,您的驅動程式可以在 DISPATCH_LEVEL 呼叫 MmAllocateNodePagesForMdlEx 。 不過,您可以在 APC_LEVEL 或以下呼叫 來改善驅動程式效能。

規格需求

需求
最低支援的用戶端 從 Windows 8 開始提供。
目標平台 Universal
標頭 wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h)
程式庫 NtosKrnl.lib
Dll NtosKrnl.exe
IRQL <= DISPATCH_LEVEL (请参阅一节。)

另請參閱

ExFreePool

KeQueryHighestNodeNumber

MDL

MEMORY_CACHING_TYPE

MM_ALLOCATE_XXX

MmFreePagesFromMdl

MmMapLockedPagesSpecifyCache