詳解Linuxカーネル読書会 - 詳解Linuxカーネル読書会 | Doorkeeperのもくもく結果。今日はページキャッシュの処理を調べました。 参考資料はUnderstanding Linux Kernelですが、長いので赤本と呼びます。
kernelは4.6を参照
buffer_head構造体の初期化。
buffer_init()で実施。
- buffer_headという名前のスラブキャッシュ作成
- buffer_head用に確保できる最大のページ数を設定
- cpu hotplugでcpuが外れた時のbuffer_headの後処理関数を設定
ページキャッシュの検索とキャッシュがなかった時に追加
赤本ではページキャッシュの追加はadd_to_page_cache()って書いているんだけど、検索した限りあまり使われていない感じです。
それよりも、add_to_page_cache_lru()や、find_or_create_page()が使われている。find_or_create_page()はページキャッシュを検索して、見つからなければページを確保してページキャッシュに登録してくれる関数。内部的にはadd_to_page_cache_lru()を使ってます。
赤本で説明されているfind_get_page()は内部の実装としてはpagecache_get_page()を呼びます。find_or_create_page()もpagecache_get_page()を呼びます。違いはpagecache_get_page()の引数fgp_flagsにFGP_CREATを設定しているかどうかです。FGP_CREATのビットが立っている場合は、ページキャッシュがなかった時にキャッシュを登録します。ページキャッシュを検索する系の関数は基本的にpagecache_get_page()を使う感じですね。
ページキャッシュの検索は、最初に find_get_entry()でページを検索します。このfind_get_entry()は赤本でradix treeを探索してるって説明のところを行っている関数っぽいです。find_get_page()の場合は、find_get_entry()でページが見つかれば処理完了です。pageが見つかった場合は参照数を増やします。find_lock_page()の場合はpage->mappingが引数で渡されたmappingと同じかをチェックします。この時はpage構造体のロックを取る必要があって、ロックが取れなければキャッシュ見つからずという感じでNULLを返します。page->mapping != mappingの場合は確保したロックの解除と、pageの参照数を減らして、再度ページキャッシュの検索を行います。 つぎにfgp_flagsにFGP_ACCESSEDが設定されていた場合はmark_page_accessed()を呼びます。これはLRUキューの操作をしたりといったところです。
ページキャッシュが見つかった場合の処理はここまでです。次にページキャッシュが見つからなかった場合です。pageがNULLでfgp_flagsにFGP_CREATが設定されている場合にキャッシュの登録があります。最初にpageをallocします(これは通常はalloc_page()で)。pageを確保できなければそこで終了で、NULLを返します。次にfgp_flags関連の処理で、FGP_LOCKが設定されていなければ、FGP_LOCKを追加します。それと、FGP_ACCESSEDが設定されていれば、__SetPageReferenced()を実行します。
最後にadd_to_page_cache_lru()でLRUにページキャッシュを登録します。 LRUに登録するのはpage構造体だけど、まだpageとaddress_space構造体は関連付いていません。なので、その関連付けが最初に行うことになります。この処理を行うのは__add_to_page_cache_locked()です。ここでpage->mappingにpagecache_get_page()に渡されたmappingを設定したり、radix treeへの登録を行ってます。__add_to_page_cache_locked()の処理が終わったら、page構造体をLRUに登録します。
- 作者: Pythonサポーターズ
- 出版社/メーカー: 技術評論社
- 発売日: 2014/10/31
- メディア: Kindle版
- この商品を含むブログ (1件) を見る