Linux Kernel(2.6)の実装に関するメモ書き

ページフォルト - 個々のハンドラ


Rev.10を表示中。最新版はこちら

ページフォルトの処理ルーチンhandle_pte_fault()から呼び出される個々のハンドラルーチンのメモ。

関連関数

do_anonymous_page()

Anonymous Page(匿名ページ)を割り当てるルーチン。
Anonymous Pageとはストレージと関連付けられていないページ。プロセスの.bssセグメントなどのページがこれに該当する。
プロセスが変数などにアクセスしてページが未割り当てだった場合は、ここでページが割り当てられる。0で初期化したページを割り当てるため、ごみが残っていることはない。

do_anonymous_page()の処理概要
if (write_access) {
    /* Writeアクセスだった */
    /* HighMemから0 fillしたページを割り当て */
    page = alloc_zeroed_user_highpage(vma, address);
    /* 割り当てたページへのPTEを作成 */
} else {
    /* Readアクセスだった */
    /* Zero Page(ページ内が0 fillされているページ)への
     * PTEを作成 */
}

/* 作成したPTEを設定 */
set_pte_at(mm, address, page_table, entry);

do_no_page()
何か初期データが存在するアドレス空間(*1)へのページフォルトを処理するハンドラ。
vmaに登録されているNo Page時のハンドラ(vma->vm_ops->nopage)を呼び出すことによって、データの格納されたページを取得してアドレス空間とのマッピングを行う。

(*1) ファイルをマップしている領域や共有領域。

do_no_page()の処理概要
/*
 * ページフォルト時のハンドラを呼び出す。
 * アドレス空間の種類によって異なるが、
 * ファイルにマップされているアドレス空間では
 * filemap_nopage()を呼び出す。
 * ハンドラはaddressに対応する空間のデータを
 * ページに格納して返す。
 */
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);

/* 共有領域以外へのWriteだった場合は、
 * COW(Copy On Write)処理を行う */
if (write_access && !(vma->vm_flags & VM_SHARED)) {
    /* HighMemからページを割り当て */
    page = alloc_page_vma(GFP_HIGHUSER, vma, address);
    /* HignMemのページへコピー (new_page => page) */
    copy_user_highpage(page, new_page, address);
    new_page = page;
    anon = 1;
}

if (mapping && unlikely(sequence != mapping->truncate_count)) {
}

if (pte_none(*page_table)) {
    /* new_pageへのPTEを作成 */
    entry = mk_pte(new_page, vma->vm_page_prot);
    /* Write属性を必要なら設定 */
    if (write_access)
        entry = maybe_mkwrite(pte_mkdirty(entry), vma);
    /* PTE(page_table)を設定して、物理ページをマッピング */
    set_pte_at(mm, address, page_table, entry);

} else {
}


do_swap_page()
do_swap_page()の処理概要
page = lookup_swap_cache(entry);
if (!page) {
    /* Swap Cacheに存在しない */
    swapin_readahead(entry, address, vma);
    page = read_swap_cache_async(entry, vma, address);
    :
}

  :
pte = mk_pte(page, vma->vm_page_prot);
if (write_access && can_share_swap_page(page)) {
    pte = maybe_mkwrite(pte_mkdirty(pte), vma);
    write_access = 0;
}

flush_icache_page(vma, page);
set_pte_at(mm, address, page_table, pte);
page_add_anon_rmap(page, vma, address);
  :
if (write_access) {
    if (do_wp_page(mm, vma, address,
                   page_table, pmd, ptl, pte) == VM_FAULT_OOM)
        ret = VM_FAULT_OOM;
    goto out;
}


---------------------------
coreの採取

do_coredump()
binfmt->core_dump() - バイナリ毎のcore採取処理を呼ぶ
(ELFの場合だとelf_core_dump())

elf_core_dump()

fill_elf_header() - ELFヘッダを作成
:
ELFヘッダ書き出し
:
current->mm->mmapの全vmaに対して
ProgramHeaderを書き出す。
(vma一つが一つのセグメント)
:
current->mm->mmapの全vmaに対して...
get_user_pages()
ページを書き出す

関連ページ

ページフォルト


最終更新 2006/12/30 22:03:16 - kztomita
(2006/12/30 20:01:52 作成)


リンク
最近更新したページ
検索