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をたどり、このページにマップしている全仮想空間からアンマップする。