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 千兆字节 - PAGE_SIZE)。 仅当有足够的页面可用时,该例程才能满足此金额的分配请求。
mmAllocateNodePagesForMdlEx 在 IRQL <= APC_LEVEL 运行。 如有必要,驱动程序可以在DISPATCH_LEVEL调用 MmAllocateNodePagesForMdlEx。 但是,可以通过在APC_LEVEL或以下调用来提高驱动程序性能。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | 从 Windows 8 开始可用。 |
目标平台 | 普遍 |
标头 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL (请参阅“备注”部分)。 |