Swap - ページアウト
Rev.1を表示中。最新版はこちら。
1. ページアウト処理の概要
1.1 ページアウトの開始
空きメモリが少くなってkswapdがwakeupされたり、alloc_pages()でFreeListからページが取れなかった場合、Inactiveリストからページを回収して空きメモリを増やそうとする(「空きページの確保」参照)。Inactiveリストをスキャンした時にPageCacheのページは(Dirtyでなければ)解放されるだけだが、匿名ページは解放前にディスク(スワップファイル)に書き出す必要があり、ページアウト処理が発生する。
Inactiveリストのページをスキャンしてページを解放する処理はshrink_list()で行なわれる。shrink_list()では、ページが匿名ページでSwapCacheに登録されていなければページアウトを開始する。
shrink_list()のページアウト関連処理
while (!list_empty(page_list)) { : /* 匿名ページでSwapCacheに登録されていない */ if (PageAnon(page) && !PageSwapCache(page)) { if (!sc->may_swap) goto keep_locked; /* スワップ領域から未使用ページを取得して、SwapCacheに登録 * そして、ページをDirty状態にする */ if (!add_to_swap(page, GFP_ATOMIC)) goto activate_locked; } /* ページがユーザ空間からマップされている * (プロセスのPTEがマップされている) */ if (page_mapped(page) && mapping) { /* このページをユーザ空間からアンマップする * (PTEを無効にする)(*1) */ switch (try_to_unmap(page, 0)) { : : case SWAP_SUCCESS: ; } } /* Dirtyページをディスクに書きだし */ if (PageDirty(page)) { switch(pageout(page, mapping)) { : : case PAGE_SUCCESS: } } }(*1) この物理ページにマップしている仮想アドレス空間は1つとは限らない(複数のプロセスで享有されている可能性がある)。try_to_unmap()はRmapをたどり、このページにマップしている全仮想空間からアンマップする。