본문 바로가기
개발/Windows

Windows 커널모드 메모리 할당과 페이지 단편화 -ExAllocatePoolWithTag

by lucidmaj7 2020. 1. 14.
728x90
반응형

Windows의 커널모드에서 메모리를 동적 할당을 할때 많이 쓰이는 함수가 바로 ExAllocatePoolWithTag이다. 커널 모드에서는 한정된 커널 메모리 자원을 사용하게 되는데 이때 메모리 할당에 대한 효율성을 따져야 한다.

보통 가상메모리 공간의 Page단위를 할당 받게 되는데 OS과목이나 시스템프로그래밍 과목에서 배운 메모리 단편화 문제가 생기게 된다. Windows WDK에 정의된 PAGE_SIZE는 32비트 기준 0x1000이다.

#if defined(_X86_)

//
// i386 Specific portions of Mm component.
//
// Define the page size for the Intel 386 as 4096 (0x1000).
//

#define PAGE_SIZE 0x1000

//
// Define the number of trailing zeros in a page aligned virtual address.
// This is used as the shift count when shifting virtual addresses to
// virtual page numbers.
//

#define PAGE_SHIFT 12L

#elif defined(_AMD64_)

//
// AMD64 Specific portions of Mm component.
//
// Define the page size for the AMD64 as 4096 (0x1000).
//

#define PAGE_SIZE 0x1000

//
// Define the number of trailing zeros in a page aligned virtual address.
// This is used as the shift count when shifting virtual addresses to
// virtual page numbers.
//

#define PAGE_SHIFT 12L

#elif defined(_ARM64_)

//
// ARM Specific portions of Mm component.
//
// Define the page size for the ARM64 as 4096 (0x1000).
//

#define PAGE_SIZE 0x1000

//
// Define the number of trailing zeros in a page aligned virtual address.
// This is used as the shift count when shifting virtual addresses to
// virtual page numbers.
//

#define PAGE_SHIFT 12L

#elif defined(_ARM_)

//
// ARM Specific portions of Mm component.
//
// Define the page size for the ARM as 4096 (0x1000).
//

#define PAGE_SIZE 0x1000

//
// Define the number of trailing zeros in a page aligned virtual address.
// This is used as the shift count when shifting virtual addresses to
// virtual page numbers.
//

#define PAGE_SHIFT 12L

#endif

0x1000 == 4096

때문에 4096보다 크게 할당 하게 된다면 페이지를 2개 할당하게되고 나머지는 낭비하게 된다. 이렇게 낭비된 페이지는 어떤 방법으로도 사용할 수 없어 귀한 자원인 메모리 낭비가 생기게 된다.

예를 들면 5KB의 메모리를 할당을 요청한다면 4KB 페이지 2개를 할당 받게되고 마지막 페이지의 3KB는 낭비가 되게 된다.

이를 회피하기 위해 4KB할당과 1KB할당을 두개의 메모리 공간을 요청하도록 권장하고 있다.

For example, on an x86, an allocation request of 5 kilobytes (KB)
returns two 4-KB pages. The last 3 KB of the second page is
unavailable to the caller or another caller. To avoid wasting nonpaged
pool, the driver should allocate multiple pages efficiently. In this
case, for example, the driver could make two allocations, one for
PAGE_SIZE and the other for 1 KB, to allocate a total of 5 KB.

참고

728x90
반응형

댓글