PageCache
Rev.12を表示中。最新版はこちら。
概要
LinuxのディスクキャッシュはPageCacheとして実装されている。PageCacheはストレージ上のファイルをキャッシュする(*1)。PageCacheはファイルの先頭から物理ページサイズ単位に区切ってページ単位にキャッシュする。このため、"Page"Cacheと呼ばれる。
ファイルのRead/WriteはPageCacheを経由する。
(*1) 同じようなディスクキャッシュとしてBufferがある。Bufferはファイルではなくディスクブロックをキャッシュする。こちらはi-nodeなどのディスク上のメタデータなどをブロックリードする時などに使用される。
PageCacheの管理方法
PageCacheはストレージ上のファイルを物理ページにマッピングして、そのアドレス空間を管理するのにstruct address_space構造体を使用する。
物理ページはaddress_space内のRadixTreeとLRUリスト(Active,Inactiveリスト)で管理される。
RadixTreeはi-node単位に持つ(i-node単位にaddress spaceがあり、そこにPageCacheのPageTreeのRootがある)。RadixTreeのキーはaddress space内でのページオフセット(ページ数)。i-nodeがブロックデバイスの場合はaddress spaceはデバイス全体を指すのでデバイス先頭からのページ数になる。
ページキャッシュはinode(正確にはaddress space)とファイル先頭からのオフセット(ページ数)でユニークに識別される。
ページキャッシュの構造を図1に示す。
- inodeのi_mappingは、このinodeに対応するaddress_spaceを指す。
- address_spaceのhostはinodeを指す。ブロックデバイスだった場合は、ブロックデバイスのinodeを指している。
- page_treeはPageCacheであるRadixTreeへのポインタ。
- RadiXTreeにはページオフセットをキーにpage構造体が登録されている。
- pageのmappingは属しているaddress_spaceを指す(つまりinodeのaddress_space)。
- indexはファイル先頭からのオフセットでファイルの何処をキャッシュしているかを示している。
- pageに該当する物理ページにindexが指しているファイルの内容がキャッシュされている。
LRUリストは各Zone(struct zone)毎にあるActive,Inactiveリストが使われる。
[関連関数]
find_or_create_page()
find_or_create_page() -> add_to_page_cache_lru() -> lru_cache_add() -> __pagevec_lru_add() -> add_page_to_inactive_list() - Inactiveリストへ登録
find_get_page(mapping, offset)
mappingのoffsetページをキャッシュしているPageCacheを検索する。
add_to_page_cache()
RadixTreeへの追加のみで、LRUリストには追加されない。
add_to_page_cache_lru()
remove_from_page_cache()
mark_page_accessed(page)
pageがInactiveリストに入っていたら、Activeリストに移動する。Activeリストに入っていたらPG_referencedを立てておく。
[フラグ]
PG_uptodate
mpage_end_io_read()参照。
[関連ページ]
物理ページ管理