ページイン

一度スワップアウトされたページへのアクセスが発生すると、CPU例外が発生する。このときlinuxはdo_swap_page関数を呼び出す。

この関数では、例外を発生した空間に対するスワップ上のブロックの内容を空き物理ページに読み込み、その物理ページをこの空間を管理するpteに登録する。

do_swap_page(タスク、仮想空間管理構造体vm_area_struct, アドレス、....)
{
        if (仮想空間管理構造体vm_area_structがswapinオペレーションを持たない) {
                swap_in()
        } else {
                vm_area_structのswapinオペレーションを呼び出す
        if(個別マップ、かつ複数プロセスから参照) {
                        pteを書きこみ禁止にする(pte_wrprotect関数)
                }
                pteを実際のページテーブルに登録(set_pte関数)
        }
}

ext2ファイルシステムのマッピング域、またファイルマッピングされていない空間のswapin処理では以下のswap_in関数が呼び出される。

swap_in(*tsk, *vma, *page_table, entry, write_access)
{
        目的のページがスワップキャッシュ中に無いか検索(lookup_swap_cache関数)
        if(スワップキャッシュ中に無い) {
                スワップデバイスからスワップキャッシュに読み込む(swapin_readahead関数)
                  このとき、前後のブロックもまとめて読みこむ(現状16ページ)
        }
        スワップ内のブロックの参照数を1減らす(swap_free関数)
        if (readアクセスの場合、または共有mmap域の場合) {
                上記で見つかったページをpteに登録
                return
        }
        if (スワップキャッシュに残っている) {
                このページをスワップキャッシュから削除(delete_from_swap_cache)
                  /* このプロセス専用のページにする */
        }
        このページを指すpteを作る(mk_pte関数)
        このページを書きこみ可、かつdirtyにする(mkwrite関数, mkdirty関数)
        このpteを実際のページテーブルに登録する(set_pte関数)
}

下図は、スワップアウトされたページに再びアクセスを開始した場合の動きを示している。スワップアウトされたページにアクセスのあった場合、そのブロックに対応するページがswapキャッシュ上にない場合、まずswapキャッシュ上にブロックを読み込みその後でそのページをPTEに登録する。

img68.gif

readアクセスによりswapinされたページ、writeアクセスであるがコピーオンライトモードで共有されたページは、PTEのWビットを落してマップする。

do_swap_page処理のコードからだけでは分かりにくいが、pte_mkwrite関数で明示的にWビットを立てない限り立たないようなアルゴリズムになっている。

コピーオンライトのページは引続き発生する例外の延長でdo_wp_page関数が呼び出され、その処理でのページの複製処理が行われる。


(NIS)HirokazuTakahashi
2000年06月11日 (日) 22時29分57秒 JST
1