Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
上記の処理のみでは十分な空きメモリを得られない場合は、プロセス空間用のメモリをswapデバイスに追い出すことにより、空きメモリ領域をつくり出す。
swap_out関数は、最もスワップすべきページを持っているプロセスを探し出し、そのプロセスにスワップアウトの要求を出す。
swap_out(解放優先度, ...) { 解放優先度を元に今回スワップアウト対象とするプロセス数を求める。 (解放優先度0の場合は、全てのタスクnr_tasks) for (上記プロセス数) { 全てのプロセスの中で、多くの物理ぺージを持ちながら しばらくスワップされていないものを選び出す。 プロセスにスワップアウト要求を出す(swap_out_mm関数) if (スワップアウト成功) return 1 } return 0; }
プロセスに出されたスワップアウト要求は以下のように分解され、最終的にはプロセス内のページに対するスワップ要求(try_to_swap_out関数)になる。
swap_out_mm関数 → swap_out_vma関数 → swap_out_pgd関数 → swap_out_pmd関数 → try_to_swap_out関数
try_to_swap_out(タスク, 仮想空間管理構造体, アドレスaddress, ...) { if(有効なページ(pte_present関数)ではない) return 0 if(最近アクセスのあったページ(pte_young関数)なら) { pteからアクセスビットを落とす(pte_mkold関数) if(ページがACTIVEなら) ページ構造体に参照ビット(PG_referenced)を立てる else ページのAGEを元に戻す(age_page_up関数) return 0 } if(ページがINACTIVEなら) { ページのAGINGを行う(age_page_down_ageonly関数) } if(ページのAGEが正なら) return if (既にスワップキャッシュ上にある(PageSwapCache関数)) { スワップブロックの参照数を上げる(swap_duplicate関数) pteに上記スワップブロックを設定(set_pte関数) ページをINACTIVEにする(deactivate_page関数) ページの解放(page_cache_release関数) return 0 } if (このページに一度も書きこみが行われていない(pte_dirty関数)) { pteのクリア(pte_clean関数) ページをINACTIVEにする(deactivate_page関数) ページの解放(page_cache_release関数) return 0 } if (仮想空間管理構造体が、swapoutオペレーションを持っている) { pteのクリア(pte_clean関数) swapoutオペレーションを呼び出す ページをINACTIVEにする(deactivate_page関数) ページの解放(page_cache_release関数) return 1 } スワップデバイス上の空きブロックを検索(get_swap_page関数) スワップブロックの参照数を上げる(swap_duplicate関数) /* プロセスからの参照分と、スワップキャッシュからの * 参照分を合わせて2となる */ スワップ対象の物理ページをスワップキャッシュに移す(add_to_swap_cache関数) pteに上記スワップブロックを設定(set_pte関数) 物理ページの内容をスワップブロックに書きこむ(rw_swap_page関数) ページをINACTIVEにする(deactivate_page関数) ページの解放(page_cache_release関数) return 1
(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:19:10, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members