- 메모리 관리 08 - 페이지 프레임 번호 데이터베이스, 페이지 파일 예약2024년 10월 16일
- 묭묭.cpp
- 작성자
- 2024.10.16.:28
메모리 관리 08 - 페이지 프레임 번호 데이터베이스, 페이지 파일 예약
페이지 프레임 번호 데이터베이스
워킹셋
- 프로세스, 시스템의 상주 메모리를 나타냄
페이지 프레임 번호 데이터베이스(PFN)
- 물리 메모리의 각 페이지의 상태를 나타냄
페이지 상태 표
PFN 데이터베이스의 구성
- 시스템에서 메모리의 각 물리 페이지를 나타내는 구조체의 배열로 구성
- 유효한 PTE는 PFN 데이터베이스 엔트리를 가리키고
- PFN 데이터베이스 엔트리는 자신을 사용하고 있는 페이지 테이블을 가리킴
- 페이지 테이블에 의해 사용된다면
- 프로토타입 PFN은 프로토타입 PTE를 가리킴
정리하면
- 유효 PTE -> PFN 데이터베이스 엔트리 -> 자신을 사용하고 있는 페이지 테이블
- 프로토타입 PFN -> 프로토타입 PTE
위 표에 나왔던 페이지 상태 중 여섯 개는 링크드 리스트 구조로 되어있음
- 메모리 관리자가 특정한 타입의 페이지를 빨리 찾을 수 있음
- 엑티브/유효 페이지, 트랜지션 페이지, 과도한 배드 페이지는 시스템 전역 페이지 리스트에 없음
- 스탠바이 상태는 우선순위로 정렬된 여덟 개의 서로 다른 리스트와 연관
페이지 리스트 다이내믹스
페이지 프레임 전환 상태도
페이지 프레임이 페이징 리스트 간 이동하는 방법
제로 페이지 요청 폴트를 위해 0으로 초기화된 페이지가 필요할 때
- 제로 페이지를 가져오는 방법
- 먼저 제로 페이지 리스트에서 하나를 가져옴
- 가져올게 없다면 프리 페이지 리스트에서 가져와 0으로 초기화
- 여기에서도 가져올게 없다면 스탠바이 리스트에서 가져와 0으로 초기화
- 제로 페이지가 필요한 이유
- 다양한 보안 요구 사항을 만족시키기 위해
- 이전 프로세스의 메모리 내용을 읽어가는 것을 방지하기 위해 반드시 초기화된 페이지 프레임이 제공되어야 함(CC에 명시되어 있음)
- 디스크로부터 페이지가 읽히는 것이 아니라면 유저 모드 프로세스에게 제로 페이지를 제공
- 디스크로부터 읽어오는 것이라면 곧바로 디스크에 있는 데이터로 초기화
제로 페이지 스레드
- 프리 리스트에서 제로 페이지를 만들어 제로 페이지 리스트로 옮김
- 제로 페이지 스레드는 게이트 객체의 시그널될 때까지 대기
- 프리 리스트의 페이지가 8개 이상이면 게이트 객체가 시그널됨
- 그러나 제로 페이지 스레드는 우선순위가 0
- 유저 스레드의 최하위 우선순위는 1
- 제로 페이지 스레드는 어떤 스레드도 동작하지 않을 때만 실행
메모리 관리자가 0으로 초기화된 페이지를 필요로 하지 않을 때
- 프리 리스트 -> 제로 페이지 리스트 -> 스탠바이 리스트 순으로 페이지를 찾아옴
- 스탠바이 리스트로부터 페이지 프레임을 가져오려면
- 해당 페이지 프레임을 가리키고 있는 유효하지 않은 PTE의 참조를 제거해야 함
- PFN 데이터베이스 내의 엔트리는 이전 사용자의 페이지 테이블에 대한 포인터를 포함
- 따라서 메모리 관리자는 빨리 PTE를 찾아 적절히 수정 가능
프로세스가 자신의 워킹셋으로부터 페이지를 포기해야 하는 경우
- 페이지가 수정되지 않았다면 스탠바이 리스트로
- 수정이 일어났다면 변경 리스트로
프로세스가 종료된 경우
- 모든 전용 페이지는 프리 리스트로 이동
- 페이지 파일 백업 섹션에 마지막 참조가 종료되고 해당 섹션에 매핑된 뷰도 없었다면 이들의 페이지도 프리 리스트로 이동
페이지 우선순위
페이지 우선순위(page priority)의 주요 목적
- 스탠바이 리스트로부터 어떤 페이지가 사용될 것인지 순서를 결정하는 것
메모리 관리자는 스탠바이 리스트를 8개로 나눠 우선순위에 맞는 페이지를 저장
- 스탠바이 리스트로부터 페이지를 가져가려하면 우선순위가 낮은 리스트에서 먼저 가져감
페이지 우선순위 설정
- 보통 스레드의 우선순위를 반영함
- 공유 페이지라면 공유 스레드 중 가장 우선순위가 높은 스레드를 반영
- 스레드는 자신의 페이지 우선순위 값을 자신이 포함된 프로세스에서 상속 받음
페이지 우선순위 변경
- 기본적으로 페이지 우선순위는 5이나 변경 가능함
- SetProcessInformation, SetThreadInformation 유저 모드 함수를 이용하여 변경
메모리 우선순위의 진가
- 페이지의 상대적인 우선순위를 상위 레벨에서 고찰할 때 드러남
- 슈퍼패치의 역할
맵 페이지 기록자와 변경 페이지 기록자
메모리 관리자는 두 개의 시스템 스레드를 이용함
- 디스크로 페이지를 저장, 그 페이지를 스탠바이 리스트로 이동시키는 일을 함
- 두 스레드
- MiModifiedPageWriter : 변경된 페이지를 페이징 파일로 저장
- MiMappedPageWriter : 변경된 페이지를 맵 파일로 저장
- 두 스레드는 데드락이 발생하는 것을 피해야 함
- 두 스레드는 모두 우선순위 18에서 동작
- 초기화 후에는 서로 다른 객체를 기다림
두 스레드에 의해 데드락이 발생하는 경우
- 맵 파일 페이지의 기록으로 인해 페이지 폴트가 발생
- 프리 페이지가 필요한데, 가용한 프리 페이지가 없으면 데드락 발생
데드락 회피 방법
- 변경 페이지 기록자로 하여금 맵 파일 I/O를 두 번째 시스템 스레드로 수행하게 함
- MiModifiedPageWriter 스레드는 일반적인 페이지 파일 I/O를 블로킹하지 않고서 대기할 수 있게 함
맵 페이지 기록자가 대기하는 이벤트 객체(18개)
- 종료 이벤트
- 맵 기록자 이벤트
- 16개의 이벤트 배열
- MiSystemParition.PageLists.MappedPageListHeadEvent에 저장된 16개의 맵 페이지 리스트와 연관
맵 기록자 이벤트가 시그널되는 상황
- 페이지 리스트 동작 중(MiInsertPageInList)
- 입력 인자 기반으로 리스트 중 하나에 페이지를 삽입
- 변경 페이지 리스트에서 파일 시스템으로 향하는 페이지 수가 16개로 도달
- 가용한 페이지 수 1024개 아래로 떨어지는 경우 시그널
- 프리 페이지를 얻으려 시도(MiObtainFreePages)
- 벨런스 셋 관리자의 일부인 워킹셋 관리자에 의해 시그널(1초에 한번)
- 워킹셋 관리자는 파일 시스템으로 향하는 변경 페이지 리스트의 페이지 수가 800개 이상이 되면 시그널
- 모든 변경 페이지를 플러시하라는 요청이 오면(MmFlushAllPages)
- 파일 시스템으로 향하는 모든 변경 페이지를 플러시하라는 요청이 오면(MmFlushAllFilesystemPages)
변경 페이지 기록자가 대기하는 이벤트(2개)
- Exit 이벤트
- MiSystemPartition.Modwriter.ModifiedPageWriterEvent에 저장된 이벤트
- 이 이벤트가 시그널 되는 경우
- 모든 페이지 플러시 요청
- 가용 페이지 수가 128페이지 이하로 떨어진 경우
- 제로 페이지 리스트 + 프리 페이지 리스트의 크기가 20000페이지 이하로 떨어지고 페이징 파일로 향하는 변경 페이지 수가 가용 페이지의 1/16과 64MB 중에 작은 값보다 클 경우
- 워킹셋이 추가적인 페이지 수용위해 줄어들 때, 가용 페이지 수가 15000개 이하인 경우
- 페이지 리스트 동작 중(MiInsertPageInList)
- 맵 기록자의 경우와 동일
- 이 이벤트가 시그널 되는 경우
변경 페이지 기록자는 위 이벤트 이후에도 다른 이벤트를 대기함(2개)
- MiSystemPartitton.Modwriter.RescanPageFilesEvent에 저장된 한 이벤트
- 페이징 파일의 재스캔이 필요함을 표시하는데 사용
- 페이징 파일 헤더 내에 있는 내부 이벤트
- 시스템이 필요시 수동으로 페이지 파일로 데이터를 플러시하라는 요청을 할 수 있게함
맵 페이지 기록하는 I/O 요청 한번으로 가능한 많은 페이지를 디스크에 쓰려고 시도
- 디스크의 연속된 위치에 페이지를 위치시키기 위해 변경 페이지 리스트의 페이지에 대한 PFN 데이터베이스의 원본 PTE 필드를 검사함으로 이뤄짐
- 리스트가 생성되면 해당 페이지는 변경 리스트에서 제거되고 I/O 요청 발생
- I/O 작업이 성공적으로 끝나는 시점에 자신의 우선순위에 맞는 스탠바이 리스트의 맨 끝으로 옮겨짐
쓰기 중인 페이지도 다른 스레드에 의해 참조될 수 있음
- 이런 상황에선 물리 페이지에 대응되는 PFN 엔트리의 참조 카운트와 공유 카운트를 하나 증가시킴
- 다른 프로세스에서 이 페이지를 사용함을 나타냄
- I/O 작업이 끝나면 변경 페이지 기록자는 공유 카운터가 0이 아님을 확인하고 스텐바이 리스트로 옮기지 않음
PFN 데이터 구조
PFN 엔트리 포멧
하나 이상의 PFN 유형에서 나타는 필드
- PTE 주소
- PTE의 가상 주소
- PTE 주소는 항상 4/8바이트 경계를 기준으로 정렬
- 두 개의 하위 비트는 PFN 엔트리 접근의 락킹 메커니즘에 사용
- 참조 카운트
- 페이지가 워킹셋에 처음 추가될 때, I/O를 위해 페이지가 락될 때 증가
- 공유 카운트 0, 혹은 락이 해제될 때 감소
- 공유 카운트가 0이면 이 페이지는 더 이상 워킹셋에 소속되지 않음
- 참조 카운트도 0이 되면 해당 페이지를 나타내는 PFN 데이터베이스 엔트리는 갱신됨
- 유형
- 액티브/유효, 스탠바이, 변경, 쓰기 없는 변경, 해제, 제로, 배드, 트랜지션 유형 타입
- 첫 번째 플래그
- 우선순위
- 스탠바이 리스트에 들어갈 것인지
- 원본 PTE 내용
- 페이지를 가리켰던 PTE의 원본 내용
- 이를 통해 물리 페이지가 메모리에 더 이상 상주하지 않을 때 복원 가능
- AWE 할당에 대한 PFN은 예외로, 대신 AWE 참조 카운트를 여기에 저장
- PTE의 PFN
- 이 페이지를 포함하는 페이지 테이블 페이지의 물리 페이지 번호
- 색상
- NUMA 노드에서 사용 - 사용 안함
- 두 번째 플래그
- PTE의 추가 정보를 인코딩 하는데 사용
나머지 필드는 PFN 유형에 따라 달라짐
페이지 파일 예약
기계적 하드 디스크의 탐색
- 실제로 디스크의 헤드를 움직여 탐색함
- 매우 값비싼 동작임 (대략 수 밀리초)
- 전체 디스크의 동작은 탐색 시간에 실제 읽기/쓰기 시간을 더한 것
세션 관리자(Smss.exe)가 페이지 파일을 생성할 때
- HDD인지 SSD인지 디스크에 질의를 함
- HDD라면 페이지 파일 예약(page file reservations) 메커니즘을 구동
- SSD의 경우 별 도움이 되지 않음
- 디스크 헤드를 움직이지 않으므로
페이지 파일 예약 기능의 처리
- 메모리 관리자의 워킹셋 관리자, 변경 페이지 기록자, 페이지 폴트 핸들러에서 처리됨
워킹셋 관리자
워킹셋 관리자는 MiFreeWsleList 루틴을 호출하여 워킹셋 정리를 수행
- 워킹셋으로부터 페이지 리스트를 받아 각 페이지에 대해 공유 카운트를 감소시킴
- 카운트 값이 0에 도달하면 해당 페이지는 변경 리스트에 위치할 수 있으며, 관련 PTE는 트랜지션 PTE로 변경됨
- 이전 유효했던 PTE는 PFN에 저장
유효하지 않은 PTE
- 페이지 파일 예약과 연관된 두 비트를 가짐
- 프리 페이지 리스트로부터 유효 페이지가 될 때 유효하지 않은 PTE는 PFN의 원래 PTE 필드에 저장됨
- 이 필드가 페이지 파일 예약을 추적하는 핵심 역할
MiCheckReservePageFileSpace 루틴
- 지정된 페이지부터 시작해 페이지 파일 예약 클러스터의 생성을 시도
- 대상 페이지 파일의 페이지 파일 예약이 비활성화되어 있는지, 페이지 파일 예약이 이미 있는지 여부를 검사
- 하나라도 해당하면 추가적 처리를 중단
- 또한 사용자 페이지가 아니라면 중단
- 특별한 이점(예측이 어려움)이 없으므로 작은 클러스터로 사용되는 경우 시도되지 않음
- 페이지드 풀 같은
- 끝으로 실제 작업을 수행하는 MiReservePageFileSpace를 호출
페이지 파일 예약에 대한 탐색
- 최초 PTE에서 시작하여 역방향으로
- 예약이 가능한 연속적인 페이지를 찾는 것이 목적
- 만약 이웃하는 페이지를 매핑하는 PTE가 디커밋, 넌페이지드 풀, 예약이 된 상태라면 사용될 수 없음
- 즉, 현재 페이지가 예약 클러스터의 하한 제약이 됨
- 그렇지 않다면 역방향으로 계속 탐색 진행
- 탐색은 가능한 많은 수의 페이지 수집을 시도하며 최초 페이지의 순방향으로 진행
- 최소 16페이지는 되어야 예약이 가능 - 최대 512
- 16페이지 = 64KB (Allocation granularity)
페이지 클러스터 계산이 완료되면
- 이 클러스터 페이지를 예약할 프리 페이지 파일 공간을 찾아야 함
- 페이지 파일 할당은 비트맵에 의해 관리됨
- 페이지 파일 예약의 경우 예약이 이뤄진 페이질르 나타내는 두 번째 비트맵이 사용
- 예약과 할당이 되지 않은 페이지 파일 공간이 존재하면 관련 비트는 예약 비트맵에서만 설정됨
- 페이지의 내용을 디스크로 쓸 때 할당 비트맵에서 이들 비트를 설정하는 것은 변경 페이지 기록자의 작업
- 충분한 페이지 파일 공간을 찾지 못하면 페이지 파일 확장 시도
- 이 시도가 이미 일어났었다면 찾아진 예약 크기에 맞게 클러스터 축소
변경 페이지 기록자
- 예약을 갖는 페이지 쓰기 작업을 특수한 경우로 다룸
- 페이지 파일에 대한 쓰기 작업의 일부분으로 사용되는 클러스터에 대한 정확한 PFN을 포함하는 MDL을 구축하기 위해 이전에 기술된 모든 수집 정보를 사용
- 클러스터 구축 작업에는 예약 클러스터를 확장할 수 있는 연속한 페이지를 찾는 작업이 포함
- 만약 클러스터 사이에 빈 공간이 존재하면 더미 페이지가 포함
- 더미 개수가 32개를 초과하면 클러스터는 해제됨
- 현재 방향으로 나아가는 작업은 완료가 되고 기록할 마지막 클러스터를 구축하기 위해 역방향으로 진행
페이지 폴트 핸들러
- 예약 비트맵과 PTE로부터 구축된 정보를 사용하여 클러스터의 시작과 마지막 지점을 결정
- 기계식 디스크 헤드의 최소 탐색으로 필요한 페이지를 효과적으로 읽어들임
반응형'윈도우 인터널즈' 카테고리의 다른 글
I/O 시스템 02 - 디바이스 드라이버 (1) 2024.10.18 I/O 시스템 01 - I/O 관리자, 인터럽트와 DPC (0) 2024.10.18 메모리 관리 06 - 스택, 가상 주소 디스크립터 (0) 2024.10.15 메모리 관리 05 - 페이지 폴트 (0) 2024.10.15 메모리 관리 04 - 주소 변환 (2) 2024.10.14 다음글이전글이전 글이 없습니다.댓글