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가 첫 번째 주소 범위에서 요청된 바이트 수를 할당할 수 없는 경우 추가 주소 범위를 반복하여 더 많은 페이지를 가져옵니다. 각 반복에서 MmAllocatePagesForMdlExSkipBytes 값을 이전 시작 주소에 추가하여 다음 주소 범위의 시작을 가져옵니다.

[in] HighAddress

할당된 페이지가 올 수 있는 첫 번째 주소 범위 끝의 실제 주소를 지정합니다.

[in] SkipBytes

할당된 페이지가 올 수 있는 이전 주소 범위의 시작에서 건너뛸 바이트 수를 지정합니다. SkipBytes 는 가상 메모리 페이지 크기의 정수 배수(바이트)여야 합니다.

[in] TotalBytes

MDL에 할당할 총 바이트 수를 지정합니다.

[in] CacheType

요청된 메모리에 허용되는 캐싱 유형을 나타내는 MEMORY_CACHING_TYPE 값을 지정합니다.

[in] Flags

이 작업의 플래그를 지정합니다. 이 매개 변수를 0으로 설정하거나 다음 MM_ALLOCATE_XXX 플래그 비트 중 하나 이상의 비트 OR로 설정합니다.

이전 목록의 마지막 4개 항목은 Windows 7 이상 버전의 Windows에서만 지원됩니다.

의미
MM_DONT_ZERO_ALLOCATION 0x00000001 할당된 페이지를 0으로 채우지 마세요. 기본적으로 MmAllocatePagesForMdlEx는 할당하는 페이지를 0으로 설정합니다. 이 작업을 건너뛰면 잠재적으로 MmAllocatePagesForMdlEx 호출의 성능을 향상시킬 수 있습니다. 그러나 할당된 페이지를 사용자 모드 프로그램에 노출하지 않거나 할당된 페이지를 사용자 모드 프로그램에 노출하기 전에 항상 페이지의 원래 콘텐츠를 덮어쓰지 않는 한 이 플래그를 사용하면 안 됩니다.
MM_ALLOCATE_FROM_LOCAL_NODE_ONLY 0x00000002 이상적인 노드에서만 페이지를 할당합니다. 이 플래그는 NUMA(비균등 메모리 액세스) 아키텍처가 있는 다중 프로세서 시스템에만 적용됩니다. Windows Vista부터 이 플래그는 모든 페이지를 현재 스레드의 이상적인 노드에서 할당해야 했음을 나타냅니다. 다른 노드에서 할당할 페이지가 없습니다. Windows Vista 이전 버전의 Windows에서 이 플래그는 모든 페이지를 로컬 노드에서 할당해야 했음을 나타냅니다. 즉, 현재 프로세서가 속한 노드에서 입니다. NUMA 다중 프로세서 시스템에 대한 자세한 내용은 NUMA 지원을 참조하세요 .
MM_ALLOCATE_FULLY_REQUIRED 0x00000004 전체 할당이 필요합니다. Windows 7부터 이 플래그를 사용하려면 요청된 모든 페이지를 할당할 수 없는 경우 MmAllocatePagesForMdlEx에서 NULL을 반환해야 합니다. 루틴은 요청된 전체 할당을 성공적으로 가져오는 경우에만 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가 성공하여 단일 연속 블록을 반환하거나 실패하고 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 는 할당하는 페이지를 0으로 채웁니다. 호출자는 MM_DONT_ZERO_ALLOCATION 플래그를 지정하여 이 기본값을 재정의하고 성능을 향상시킬 수 있습니다.

MM_DONT_ZERO_ALLOCATION 플래그를 지정하면 MmAllocatePagesForMdlEx 가 할당하는 메모리는 초기화되지 않습니다. 커널 모드 드라이버는 드라이버가 잠재적으로 권한 있는 콘텐츠가 누출되지 않도록 메모리를 사용자 모드 소프트웨어에 표시하려는 경우 먼저 이 메모리를 0으로 설정해야 합니다. 이 플래그에 대한 자세한 내용은 MM_ALLOCATE_XXX 참조하세요.

MmAllocatePagesForMdlEx가 단일 호출에서 할당할 수 있는 최대 메모리 양은 (4기가바이트 - PAGE_SIZE)입니다. 루틴은 충분한 페이지를 사용할 수 있는 경우에만 이 금액에 대한 할당 요청을 충족할 수 있습니다.

MmAllocatePagesForMdlEx는 IRQL <= APC_LEVEL 실행됩니다. MmAllocatePagesForMdlEx의 호출자는 DISPATCH_LEVEL 있을 수 있습니다. 그러나 APC_LEVEL 이하에서 를 호출하여 드라이버 성능을 향상시킬 수 있습니다.

요구 사항

요구 사항
대상 플랫폼 유니버설
헤더 wdm.h(Wdm.h, Ntddk.h, Ntifs.h 포함)
라이브러리 NtosKrnl.lib
DLL NtosKrnl.exe
IRQL 설명 섹션을 참조하십시오.
DDI 규정 준수 규칙 IrqlMmApcLte(wdm)

추가 정보

ExFreePool

MEMORY_CACHING_TYPE

MmAllocatePagesForMdl

MmFreePagesFromMdl

MmMapLockedPages