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开始可用。
目标平台 通用
标头 wdm.h(包括 Wdm.h、Ntddk.h、Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL (请参阅备注部分。)

另请参阅

ExFreePool

KeQueryHighestNodeNumber

MDL

MEMORY_CACHING_TYPE

MM_ALLOCATE_XXX

MmFreePagesFromMdl

MmMapLockedPagesSpecifyCache