[Project 3] Virtual Memory (2)
16769 ワード
Uninitialized page.
pintos仮想メモリのpageタイプは3種類あります.
どんな役を演じるかを理解するにはPintosLazy loadingの大図を理解する必要があります.
Project 2への移行中、User Processを実行するために必要なすべてのデータは、実行前にkernel threadから設定フェーズの物理メモリにアップロードされます.また、pml 4の役割は、アップロードデータを指すアドレスと、ユーザへのページアドレスとをマッピングすることである.(install_page function)
ただし、実行に必要なすべてのデータを最初に物理メモリに配置するのではなく、必要に応じてpage fault handlerを使用してディスクから物理メモリにデータを昇格させることができます.ユーザに渡されるページタイプによって、後続の初期化関数と物理メモリにアップロードされるswap in関数は異なります.これらのページの準備過程は統一ページ段階であると考えられる.
すべてのタイプでよく見るよりも、最初にUninitTypeでユーザーに投げつけられたページがどのような形で現れ、どのような内容が含まれているかの関数を見てみましょう.
最初の実行時にユーザーに投げ出された仮想ページについて、
bool vm_alloc_page_with_initializer (enum vm_type type, void *upage, bool writable, vm_initializer *init, void *aux) {
ASSERT (VM_TYPE(type) != VM_UNINIT)
struct supplemental_page_table *spt = &thread_current ()->spt;
/* Check wheter the upage is already occupied or not. */
if (spt_find_page (spt, upage) == NULL) {
/* TODO: Create the page, fetch the initialier according to the VM type,
* TODO: and then create "uninit" page struct by calling uninit_new. You
* TODO: should modify the field after calling the uninit_new. */
struct page* page = (struct page*)malloc(sizeof(struct page));
typedef bool (*initializerFunc)(struct page *, enum vm_type, void *);
initializerFunc initializer = NULL;
switch(VM_TYPE(type)) {
case VM_ANON:
initializer = anon_initializer;
break;
case VM_FILE:
initializer = file_backed_initializer;
break;
}
uninit_new(page, upage, init, type, aux, initializer);
// page member 초기화
page->writable = writable;
// hex_dump(page->va, page->va, PGSIZE, true);
/* TODO: Insert the page into the spt. */
return spt_insert_page(spt, page);
}
err:
return false;
}
上の関数はpageを作成し、sptにないことを確認します.現在はuninittypeですが、以降のタイプをパラメータとして受信し、ページのstruct memberを入れます.つまり、この関数の終了時に生成されるページはUninit typeになりますが、ユーザーがアクセス権を持っている場合はpageエラーが発生し、その後に追加されたpage typeに基づいてinitialize関数が実行されます.
このように生成されたページは、vm−claim−page関数を介してマッピングを要求する.イニシエータ関数にSPTを加えた.マッピング中、vm-do-claim-pageは物理フレームと仮想ページを決定的にマッピングし、直接接続し、swap in関数によってディスク(swap space)から物理メモリに昇格させる.
ファイルバックアップページでは、lazy-load-segment関数を使用してのみ、実行可能なファイルに関連するデータをディスクから物理メモリにアップロードできます.
整理すると、vm-claim-pageは、ユーザが転送する仮想ページに物理フレームとマッピングがない場合に使用される関数であり、lazy-load-segmentは、物理フレームにディスクからファイル関連データ(swap-in)をロードする関数である.
これらは、ユーザー・プログラムのページ・ポーリングに由来します.
Page fault handling.
PagePaultではいったい何をして、それらの仕事をすることができますか?
vm-try-handle-faultです
bool vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr UNUSED,
bool user UNUSED, bool write UNUSED, bool not_present UNUSED) {
struct supplemental_page_table *spt UNUSED = &thread_current ()->spt;
// struct page *page = NULL;
/* TODO: Validate the fault */
/* TODO: Your code goes here */
if (is_kernel_vaddr(addr)) {
return false;
}
void *rsp_stack = is_kernel_vaddr(f->rsp) ? thread_current()->rsp_stack : f->rsp;
if (not_present){
if (!vm_claim_page(addr)) {
if (rsp_stack - 8 <= addr && USER_STACK - 0x100000 <= addr && addr <= USER_STACK) {
vm_stack_growth(thread_current()->stack_bottom - PGSIZE);
return true;
}
return false;
}
else
return true;
}
return false;
}
関数で確認できるinitializer関数はありません.ユーザーはUninit typeのページ(初期実行時)を受信し、アクセス時にpage faultが発生したためです.したがって、vm-claim-page(=>仮想ページと物理フレームのマッピング)から実行されるコードが表示されます.ここまでは上図の4番の手順に相当します.
その後の第5のプロセスは、lazy−load−seagementまたはanon−swap−inなどの各ページタイプに対する(File back type pageを知りたいなら)関数によって行われる.
bool lazy_load_segment (struct page *page, void *aux) {
/* TODO: Load the segment from the file */
/* TODO: This called when the first page fault occurs on address VA. */
/* TODO: VA is available when calling this function. */
struct file *file = ((struct container *)aux)->file;
off_t offsetof = ((struct container *)aux)->offset;
size_t page_read_bytes = ((struct container *)aux)->page_read_bytes;
size_t page_zero_bytes = PGSIZE - page_read_bytes;
file_seek(file, offsetof);
if (file_read(file, page->frame->kva, page_read_bytes) != (int)page_read_bytes) {
palloc_free_page(page->frame->kva);
return false;
}
memset(page->frame->kva + page_read_bytes, 0, page_zero_bytes);
return true;
}
これにより、実行に必要なデータを物理フレームにアップロードし、フレームと仮想ページをマッピングした後、page faultが最後に発生したコマンドからユーザを再実行させることができる.Reference
この問題について([Project 3] Virtual Memory (2)), 我々は、より多くの情報をここで見つけました https://velog.io/@phw1996/Project-3-Virtual-Memory-2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol