일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- BFS
- 동적 프로그래밍(Dynamic Programming)
- 백준 2504번
- 백준 10000번
- 이분 그래프(Bipartite Graph)
- 트리(Tree)
- 위상 정렬(Topological Sort)
- 백준 9012번
- 백준 1948번
- 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)
- 백준 17608번
- 백준 2261번
- 백준 2493번
- BFS(Breadth First Search)
- 분할 정복(Divide and Conquer)
- DFS
- 백준 18352번
- DFS(Depth First Search)
- 큐(Queue)
- 백준 21606번
- 백준 1707번
- 그래프(Graph)
- 이분 탐색(Binary Search)
- 스택(Stack)
- 다익스트라 알고리즘(Dijkstra Algorithm)
- 백준 2812번
- DFS & BFS
- 그리디 알고리즘(Greedy Algorithm)
- 위상 정렬(Topology Sort)
- 알고리즘 개념
- Today
- Total
Always Be Wise
Project_3 : Virtual Memory - Memory Management(1) 본문
Project_3 : Virtual Memory - Memory Management(1)
bewisesh91 2022. 1. 14. 23:18Page Structure an Operations
struct page
include/vm/vm.h에 정의되어 있는 page 구조체는 가상 메모리의 페이지를 나타내는 자료구조이다.
해당 자료구조에는 page에 관하여 알아야 할 모든 정보들이 담겨 있다.
현재 page 구조체는 아래와 같다.
struct page {
const struct page_operations *operations;
void *va; /* Address in terms of user space */
struct frame *frame; /* Back reference for frame */
union {
struct uninit_page uninit;
struct anon_page anon;
struct file_page file;
#ifdef EFILESYS
struct page_cache page_cache;
#endif
};
};
살펴보면 page operation, virtual address, physical frame 등이 포함되며, 추가적으로 union 필드를 갖고 있다.
union은 메모리 영역에 서로 다른 유형의 데이터를 저장할 수 있는 특별한 데이터 유형이다.
union에는 다양한 멤버 변수가 있지만, 한 번에 하나의 멤버 변수만이 값을 가질 수 있다.
즉, Pintos 시스템 내의 page는 uninit_page, anon_page, file_page 또는 page_cache 일 수 있다.
예를 들어, page가 익명의 page인 경우, page 구조체는 하나의 멤버 변수로 anon_page anon을 갖는다.
anon_page는 익명 page에 필요한 모든 정보를 포함한다.
Page Operations
include/vm/vm.h 에서 정의한 대로 page는 VM_UNINIT, VM_ANON 또는 VM_FILE일 수 있다.
page에는 swapping in, swapping out, destroying과 같은 다양한 액션들이 있다.
그런데 각 page 유형마다 액션 별로 요구되는 단계와 작업들이 다르다.
다시 말해, VM_ANON 페이지와 VM_FILE 페이지에 대해 서로 다른 destroy 함수가 호출되어야 한다.
한 가지 방법은 각 함수 별로 switch-case 구문을 사용하여 각 케이스를 처리하는 것이다.
이를 다루기 위해 객체 지향 프로그래밍의 "클래스 상속" 개념을 도입한다.
정확히는 C 언어에서 클래스나 상속은 없다. 비슷한 방식으로 이러한 개념을 실현하기 위해 함수 포인터를 사용한다.
함수 포인터는 메모리 내의 함수나 실행 가능한 코드를 가리키는 포인터이다.
이는 런타임 값에 기반하여 특정 함수를 손쉽게 호출할 수 있는 방법을 제공한다.
아래에서 살펴보겠지만, 단순히 destroy(page) 함수를 호출하는 것만으로 충분하다.
컴파일러가 적절한 함수 포인터를 호출함으로써 페이지 유형에 따른절한 destroy 루틴을 선택할 것이다.
page_operations 구조체는 include/vm/vm.h에 정의되어 있다.
해당 구조체는 3개의 함수 포인터를 갖고 있는 함수 테이블이라고 할 수 있다.
struct page_operations {
bool (*swap_in) (struct page *, void *);
bool (*swap_out) (struct page *);
void (*destroy) (struct page *);
enum vm_type type;
};
include/vm/vm.h의 page 구조체를 살펴보면, 그 안에 page_operations 형의 operations 필드가 있는 것을 알 수 있다.
vm/file.c로 가면, file_ops라는 page_operations 구조체가 있다. 이는 filed-backed page에 대한 함수 포인터 테이블이다.
.destroy 필드는 page를 파괴하는 file_backed_destroy 함수를 값으로 갖고 있다.
다음은 file_backed_destroy 함수가 함수 포인터 인터페이스로 호출되는 과정이다.
우선, vm/vm.c의 vm_dealloc_page(page) 함수가 호출되고, 이때의 page가 file-backed page(VM_FILE)이라고 가정하자.
vm_dealloc_page(page) 함수 내부에서 destroy(page) 함수를 호출한다.
destroy(page) 함수는 include/vm/vm.h에 아래와 같이 매크로로 정의되어 있는데,
이는 destroy(page) 함수를 호출하는 것이 실제로는 page 구조체로부터 시작된 호출임을 알려준다.
#define destroy(page) if ((page)->operations->destroy) (page)->operations->destroy (page)
Implement Supplemental Page Table
Pintos에서는 가상 메모리와 물리 메모리의 매핑을 관리하기 위한 페이지 테이블(pml4)을 갖고 있다. 그러나 이것만으로는 충분하지 않다.
페이지 폴트 및 자원 관리를 처리하기 위해서는 각 페이지에 대한 추가적인 정보를 갖는 supplementary page table이 필요하다.
따라서, 세 번째 프로젝트의 첫 번째 작업은 supplementary page table의 몇 가지 기본 기능을 구현하는 것이다.
Implement supplemental page table management functions in vm/vm.c
void supplemental_page_table_init (struct supplemental_page_table *spt);
supplemental page table을 초기화하는 함수이다. 사용할 자료구조(hash table or bitmap 등)를 선택해야 한다.
이는 새로운 프로세스가 시작될 때(userprog/process.c의 initd), 프로세스가 분기될 때(userprog/process.c의 __do_fork) 호출된다.
struct page *spt_find_page (struct supplemental_page_table *spt, void *va);
supplemental page table에서 va에 해당하는 page 구조체를 찾는 함수이다. 실패하면 NULL을 반환한다.
bool spt_insert_page (struct supplemental_page_table *spt, struct page *page);
page 구조체를 supplemental page table에 삽입하는 함수이다.
해당 함수는 supplemental page table에서 가상 주소가 존재하지 않는지를 확인해야 한다.
Frame Management
모든 페이지들이 메모리에 대한 메타 데이터만을 갖고 있는 것이 아니다. 그러므로 우리는 물리 메모리를 관리할 다른 전략이 필요하다.
include/vm/vm.h에 물리적 메모리를 나타내는 frame 구조체가 있다. 현재 구조는 아래와 같다.
kva(kernel virtual address)와 page 두 개의 필드만 있다. 아래 프레임 관리 인터페이스를 구현할 때 멤버를 더 추가할 수 있다.
/* The representation of "frame" */
struct frame {
void *kva;
struct page *page;
};
Implement vm_get_frame, vm_claim_page and vm_do_claim_page in vm/vm.c
static struct frame *vm_get_frame (void);
palloc_get_page( ) 함수를 호출하여 사용자 풀(user pool)에서 물리 페이지를 가져오는 함수로,
사용자 풀에서 성공적으로 페이지를 가져오면, 프레임을 할당하고 프레임의 멤버들을 초기화한다.
vm_get_frame을 구현한 후에는 모든 사용자 공간 페이지(PALLOC_USER)를 이 함수를 통해 할당해야 한다.
페이지 할당 실패의 경우, 아직은 스왑 아웃(swap out) 처리를 할 필요가 없다. 단지 PANIC("todo") 정도로 표시하면 된다.
bool vm_do_claim_page (struct page *page);
페이지를 가져와 물리 프레임을 할당하는 함수이다. vm_get_frame( ) 함수를호출하여 프레임을 가져온다. 이후 MMU를 설정한다.
즉, 가상 주소에서 페이지 테이블의 물리 주소로의 매핑을 추가한다.
bool vm_claim_page (void *va);
가상 주소(va)를 할당하기 위해 페이지를 가져오는 함수이다.
먼저 페이지를 가져온 다음, 해당 페이지로 vm_do_claim_page( ) 함수를 호출해야 한다.
'카이스트 정글 - 프로젝트 > Pintos' 카테고리의 다른 글
Project_3 : Virtual Memory - Anonymous Page(1) (0) | 2022.01.21 |
---|---|
Project_3 : Virtual Memory - Memory Management(2) (0) | 2022.01.19 |
Project_3 : Virtual Memory - Introduction (0) | 2022.01.11 |
Project_2 : User Programs - Weekly I Learned (0) | 2022.01.10 |
Project_2 : User Programs - System Calls(2) (0) | 2022.01.07 |