본문 바로가기

정글캠프-WIL/핀토스

pintos - vm [file-backed (swap_in, swap_out, destroy)]

https://gyumingomin.tistory.com/99

 

pintos - anon [swap in, swap out, destroy]

접은글 : 현재까지 진행한 내용 정리와 앞으로 해야할 전체적인 흐름 구조 나열... (보기가 어려우므로 요약)더보기더보기더보기page fault가 발생하면 커널은 먼저 fault가 난 유저 가상 주소가 suppl

gyumingomin.tistory.com

위 내용을 먼저 살펴보고 오시길 추천드립니다.

1. File-Backed Page Strategy (파일 백업 페이지 전략)

ⓐ. struct file_page

ⓑ. vm_file_init

파일 기반 VM의 전역 초기화 함수인데, 현재는 특별한 전역 자료구조가 없어 비워둠

ⓒ. file_backed_initializer

bool file_backed_initializer (struct page *page, enum vm_type type, void *kva);

접은글 : file_backed_initializer 구현

1. page의 uninit 멤버 변수에 있던 aux 정보를 가져와서 file-backed page에서 계속 사용할 수 있도록 page->file에 복사
2. aux는 lazy loading 시 필요한 파일 정보(file, ops, read_bytes, zero_bytes)를 임시로 담아둔 힙 메모리이기 때문에 free(aux)로 메모리 해제

3. file_backed_swap_in은 mmap page가 처음 로드될 때도 사용되고, file-backed page가 eviction된 뒤 다시 메모리에 올라올 때도 사용

2. file_backed_swap_in

static bool file_backed_swap_in (struct page *page, void *kva);

접은글 : file_backed_swap_in 구현

실제로 코드를 보면 이전에 lazy_load_segment를 구현했던 것과 엄청 비슷하다는 것을 느낄 수 있다.

https://gyumingomin.tistory.com/97

 

pintos - vm [lazy_load_segment]

지금까지 VM 구현에선 각 프로세스마다 Supplemental Page Table(SPT) 해시 테이블을 생성하도록 구성하고 이후 아직 물리 프레임이 할당되지 않은 uninit 페이지를 SPT에 등록해두고, 실제로 해당 가상 주

gyumingomin.tistory.com

lazy_load_segment:
- lazy loading용 임시 aux/file을 직접 가지고 있음
- 실패하면 이 임시 자원을 정리해야 함
- 그래서 file_close 같은 정리가 들어갈 수 있음

file_backed_swap_in:
- page->file에 이미 저장된 정보를 사용함
- file_page->file은 mmap page가 계속 참조해야 하는 backing file
- 여기서 닫아버리면 이후 재시도, munmap, destroy 흐름에서 문제가 생길 수 있음
- 그래서 실패 여부만 false로 알려줌

3. file_backed_swap_out

static bool file_backed_swap_out (struct page *page);

접은글 : file_backed_swap_out 구현

ⓐ. pml4_is_dirty

PTE_D는 Page Table Entry(PTE)의 Dirty bit를 의미한다. (0x40 = 0100 0000(2)) 

pml4_is_dirty()는 현재 가상 페이지의 PTE를 찾아, Dirty bit(PTE_D)가 1인지 확인하는 함수다.

Dirty bit가 1이라는 것은 해당 페이지가 메모리에 올라온 뒤 CPU에 의해 write된 적이 있다는 의미이고,

CPU가 페이지에 write를 수행하면 Dirty bit를 자동으로 1로 설정한다.

예를 들어 mmap된 페이지가 lazy loading으로 메모리에 올라온 뒤,

char *p = mmap(...);
p[0] = 'A';

와 같이 값을 수정하면, CPU는 해당 페이지의 PTE Dirty bit(PTE_D)를 1로 변경한다.

운영체제는 이를 통해 "이 mmap 페이지가 수정되었으므로 eviction 또는 munmap 시 파일에 다시 write-back 해야 한다"는 것을 판단할 수 있다.

ⓑ. file_write_at

현재 메모리(frame)에 있는 내용을 원본 파일에 다시 저장(write-back)하는 함수

mmap이 수정되었을 경우, 현재 frame(kva)에 존재하는 데이터를 원본 파일의 ofs 위치에 다시 기록하는 코드

접은글 : file_wrtie_at -> inode_write_at

https://gyumingomin.tistory.com/97

 

pintos - vm [lazy_load_segment]

지금까지 VM 구현에선 각 프로세스마다 Supplemental Page Table(SPT) 해시 테이블을 생성하도록 구성하고 이후 아직 물리 프레임이 할당되지 않은 uninit 페이지를 SPT에 등록해두고, 실제로 해당 가상 주

gyumingomin.tistory.com

위 내용을 코드만 적어놨는데, 위 사이트에서 file_read_at을 가볍게 이해하면 file_write_at도 비슷한 흐름으로 메모리에 있는 내용을 원본 파일에 다시 어떻게 저장하는지를 대략 이해할 수 있게 된다.

ⓒ. pml4_set_dirty

https://gyumingomin.tistory.com/95

 

pintos - vm_do_claim_page 구현

https://gyumingomin.tistory.com/94 vm - Page Fault 구현https://gyumingomin.tistory.com/92 Pintos - vm [페이지 할당 초기화 과정을 위한 흐름도]https://gyumingomin.tistory.com/91 Pintos - SPT(Supplemental Page Table)와 Hash TableSPT(Supplem

gyumingomin.tistory.com

위 코드는 이 주소의 pml4_set_accessed를 보면 이해할 수 있게 된다. (가장 아래에 위치)

1. 현재 설정할 dirty파일여부가 true일 경우 실제 pte에 0x40을 넣어준다. 반대의 경우 지워준다.

2. 현재 활성화된 pml4를 수정한 경우 TLB를 지워준다는 의미

ⓓ. pml4_clear_page

1. pml4 테이블을 따라가 현재 페이지의 pte를 찾는다.

2. 현재 설정할 present여부가 true일 경우 실제 pte에 0x1을 지워준다.

3. 현재 활성화된 pml4를 수정한 경우 TLB를 지워준다는 의미

정리
1. mmap된 file-backed page가 dirty인지 여부를 확인하고 메모리에 올라온 뒤 write가 발생했는지 PTE_D로 확인
2. dirty라면 file_write_at()을 통해 현재 frame->kva에 있는 내용을 원본 파일의 ofs 위치에 write-back한다.
2. 파일 쓰기가 완료되었을 경우 dirty bit를 0으로 변경한다.
3. swap out되었기 때문에 현재 메모리에 있는 pml4 매핑을 제거한다.
4. page와 frame의 연결을 끊어준다.

4. file_backed_destroy

static void file_backed_destroy (struct page *page);

접은글 : file_backed_destroy 구현

1. 현재 페이지에 frame이 연결되어 있다면, mmap된 file-backed page가 dirty인지 확인한다.

2. dirty라면 frame->kva에 있는 내용을 원본 파일의 ofs 위치에 write-back한다.

3. 현재 PML4 매핑을 제거한 뒤, page와 frame의 연결을 끊어준다.

4. file-backed page가 사용하던 파일 객체를 닫는다.