Linux memo 2019/10/26

● ページキャッシュの読み込みの実装あたり
ふつうのファイルのページキャッシュ(bread()系)は、一度inodeからブロックデバイスの位置を引っ張るbmapあたりを経由しmountしているパーティションごとのバッファへ行き着く(ハズ)。sb_bread()あたりは下記の記事が詳しい。
Linuxカーネルのページキャッシュとbuffer_head、address_spaceとの関係について
https://qiita.com/todok-r/items/334e721533c462831a12

このへんを確認することで、ページキャッシュへの読み込みや、逆に破棄やらの概要が見えてくる。

● 任意のページキャッシュを破棄したい場合
ありそうでなかなかないようなテーマで書かれた記事が下記。
Proof of Concept: Linux カーネルモジュールで特定のディレクトリ以下の dentry キャッシュを破棄する - hibotaの日記
https://hiboma.hatenadiary.jp/entry/2019/10/09/123138

Proof of Concept: Linux カーネルモジュールで特定のディレクトリ以下の dentry キャッシュを破棄する (2) - hibotaの日記
https://hiboma.hatenadiary.jp/entry/2019/10/15/200254

>「この内容も Qiita で詳しくまとめてる人がいるので」
私のことかもしれないとウッホしながら、、
使用するトータルメモリサイズの兼ね合いで、dentryはまだましで上記に書かれた方法の以前にdrop_cachesに1を書く方法でも(**万個のdentryのような場合を除いて)それほどコストがかからないけど、ページキャッシュの場合は問題になりやすい。

手っ取り早く思いついたのがユーザランドでMADV_DONTNEEDしまくる方法(MADV_FREEではない※2019/11/27に訂正)だけど、この方法だとユーザランドでdirectory walkしないといけないので、逆にdentryを作ってしまう。とはいえ「任意のpath」だとこれしか方法がないと思う。

「任意のpath」を諦めて「任意のmount」だと、上の記事に書かれたようなやり方が出てくる。個人的にはremountでも捌けるというのは盲点だった。ただこの方法、drop_cachesの場合もそうなんだけど、dirtyなinodeの取り扱いが懸念点。というか、dirtyだったりまさにinode処理中だったりすると、諦めるかエラー返して上位でリトライしてもらうかくらいしか方法がない気がする。

● ググラビリティ
shrink_dcache_sb() -- mountごとのdentryを破棄する。
evict_inodes() -- mountごとのinodeのページキャッシュを破棄する。使用中(==openしてる)のinodeは破棄しないのが注意点か。
invalidate_inodes()-- 使用中でも破棄する。dirtyの扱いは引数kill_dirtyで指定。
invalidate_bdev() -- bdev上のinodeに結びつかないpageも破棄してくれそう。ということは実はユーザランドからBLKFLSBUFするだけでよい?
__invalidate_device() -- 上までを踏まえて、dcacheもinode pageも破棄してくれるこの関数が無難に見える。
invalidate_bh_lrus() -- percpuなbufの参照用キャッシュがあるらしい。こんな局所的なのが必要なほど性能にシビアなのか、まぁそうか。
kill_bdev() -- dirtyなのもやっちゃいそう。kernel/mm/page-writeback.cの__cancel_dirty_page()に書かれたコメントがなにか怖い。

● 宣伝
Linuxのdrop_cachesにwriteした時の動きを追う- Qiita
https://qiita.com/rarul/items/a6688fd2a06d960cb5ea

このブログ記事について

このページは、らるるが2019年10月26日 18:31に書いたブログ記事です。

ひとつ前のブログ記事は「「超例解Linuxカーネルプログラミング」読んだ」です。

次のブログ記事は「Linux memo 2019/11/07」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

Powered by Movable Type 7.9.0