[Stack Trace]System PTEs 는 무엇일까요?

"이 문서는 https://msdn.microsoft.com/en-us/magazine/default.aspx 의 번역이며 원래의 자료가 통보 없이 변경될 수 있습니다. 이 자료는 법률적 보증이 없으며 의견을 주시기 위해 원래의 site를 방문하실 수 있습니다. (https://msdn.microsoft.com/en-us/magazine/dd420461.aspx)"

System PTEs는 무엇일까요?

Bob Golding and David Butler

 

내용
어떤 API들이 이 주소들을 Map 하는데 사용될까?

Bugcheck 0x3F 상황에서 Track PTEs 가 항상 필요한 것은 아니다

커널 스택

 

System PTEs 는 모든 PTEs 와 비슷하게 시스템 어드레스 공간을 나타내는데 사용 됩니다. 그렇다면 시스템 리소스에서 이 두 PTEs가 다른 점은 무엇일까요? System PTEs 는 시스템을 위해서만 사용되고 System PTEs 는 시스템 어드레스 공간 Map 의 동적인 슬롯 입니다. 다시 말해 많은 어드레스 공간이 시스템 어드레스 공간에 Map 되어 있고 동적으로 버퍼 또는 커널 스택 등에 Map 되는 것 입니다. 이 주소공간은 넌페이지드풀과 페이지드 풀 사이에 위치하고 아래 정보는 mi386.h 에서 발최 한 것 입니다.

E1000000  | 페이지 시스템 공간                       |
                  |   커널 모드만 접근 가능                |
                  |                                                    |
                  |                                                    |
                  +-----------------------------------------+
                  |                                                     |
                  | 시스템 PTE 공간 – 커널 스택,         |
                  |  MDL을 시스템 가상 주소에 Map함 |
                  |   커널 모드만 접근 가능                  |<----- 예약된 동적 map 을 위한 공간
                  |   Kernel mode access only.         |
                  |                                                    |
                  +-----------------------------------------+
                  |                                                     |
                  | 넌페이지 시스템 공간                    |
                  |   커널 모드만 접근 가능                 |
                  |                                                     |
                  +------------------------------------------+
FFBE0000  | 크래시 덤프 드라이버 역억               |
                  |  커널 모드만 접근 가능                    |
                  +------------------------------------------+
 

시스템 PTEs 의 크기는 페이지드와 넌페이지드 풀의 크기에 따라 변경 됩니다. 또한 시스템 주소 공간으로 /3GB 와 같은 옵션에 영향을 받습니다.

 

어떤 API들이 이 주소들을 Map 하는데 사용될까?
MiMapLockedPagesInUserSpace, MiUnmapLockedPagesInUserSpace, MmMapLockedPages, and MmUnmapLockedPages 와 같은 API 들이 주소를 Map 하는데 사용 됩니다. 이 API 들은 버퍼를 동적 주소 공간에 map 하는 역할을 하며 전체 버퍼를 map 하고자 할 때 버퍼의 크기가 얼마나 많은 연속된 page 가 사용될 지 결정 합니다.

위에서 보신 것과 같이 모든 Map API 에는 Unmap API 가 존재 합니다. 이것은 아주 중요한데 모든 버퍼는 Unmap 되어야 합니다. Map 된 page 가 Unmap 되지 않는다면 No more PTEs 문제가 발생할 것 입니다. System PTEs 가 낮아 질 경우 성능 또한 낮아질 것이며 Bugcheck 3F 가 나타날 것 입니다. 하지만 NT 에서 리소스를 잘 처리하기 때문에 이러한 현상은 자주 발생하지 않습니다.

 

Bugcheck 0x3F 상황에서 Track PTEs 가 항상 필요한 것은 아니다
System Ptes 가 부족한 현상은 보통 TrackPtes 를 사용하여 얼마나 많은 PTEs 가 사용되었는지 확인 합니다. 하지만 가끔은 이것이 문제를 찾는데 충분하지 않을 수 있습니다. TrackPtes 는 sysptes.c 에 구현되어 있지 않기 때문에 모든 System PTEs 사용이 기록되지는 않고 MiReserveSystemPtes 와 같은 함수를 호출할 때 기록 됩니다.

 

커널 스택

Sysptes 를 소모하지만 기록되지 않는 요인 중 하나가 커널 스택 입니다. 다행이도 메모리 매니저에서 몇 가지 전역 변수를 통해 얼마나 많은 sysptes 가 커널 스택에 사용되었는지 알 수 있게 해 줍니다. 아래의 예를 보면 23,000 개의 sysptes 가 존재 합니다. 이것은 아주 작은 숫자로 /3GB 가 적용 되었을 경우 많이 나타나는 결과 입니다. 17,860 개의 sysptes 가 커널 스택으로 사용되고 있으며 프로세스와 스레드의 분석 만으로는 문제점을 찾을 수 없습니다. 문제점은 사용자의 응용 프로그램이 많은 GDI 스레드를 사용하고 있다는 것 입니다. 장비의 메모리 상태를 분석 한 후 system ptes 의 갯수를 늘리는 것 과 같은 조취를 취해야 할 것 입니다.

1: kd> !sysptes

System PTE Information
  Total System Ptes 23006

1: kd> dc nt!MmKernelStackPages l 1
80483680  000045c4                             .E..
1: kd> ?45c4
Evaluate expression: 17860 = 000045c4

1: kd> dc MmLargeStacks l 1
8048368c  0000037b
1: kd> dc MmSmallStacks l 1
8048367c  00000385
1: kd> ?37b*f
Evaluate expression: 13365 = 00003435
1: kd> ?385*3
Evaluate expression: 2703 = 00000a8f
1: kd> ?3435+a8f+37b+385
Evaluate expression: 17860 = 000045c4

역자주) UI thread 의 경우 Stack 이 15page(60kb) 이고 일반 Thread 의 경우 3page(12kb) 그리고 각각의 커널 스택에 보호 페이지가 1씩 필요하다.

Bob Golding 은 1997년부터 Microsoft 에서 일하고 있습니다. 그는 Global Escalation Services team 의 Senior Escalation Engineer 로 많은 고객의 중요 문제를 지원하고 있습니다.

David Butler 은 2000년부터 Microsoft 에서 일하고 있습니다. 그는 Global Escalation Services team 의 Escalation Engineer 로 많은 고객의 중요 문제를 지원하고 있습니다.