読者です 読者をやめる 読者になる 読者になる

kmem_cache_create()のざっくりとした流れのめも

linux kernel

Linuxでスラブキャッシュを新しく作成する場合はkmem_cache_create()を使用する。これのラッパーとしてKMEM_CACHE()というマクロもあって、これは構造体の型名とメモリ確保時に使用するフラグ(GFP_KERNEL等)を渡すだけの便利マクロ。

処理の流れは下記の通り。処理的に主要じゃない関数の呼び出しは入ってません。例えばstruct kmem_cache構造体のメモリ確保に使うkmem_cache_zalloc()とか。

kmem_cache_create()
  --> get_online_cpus()@kernel/cpu.c  ①
  --> get_online_mems()@mm/memory_hotplug.c  ②      
  --> kmem_cache_sanity_check()@mm/slab_common.c   ③
  --> __kmem_cache_alias()@mm/slub.c  ④
    --> find_mergeable()@mm/slub.c   ⑤
  --> do_kmem_cache_create()@mm/slab_common.c  ⑥
    --> memcg_alloc_cache_params()@mm/memcontrol.c  ⑦
    --> __kmem_cache_create()@mm/slub.c   ⑧
  --> put_online_mems()@mm/memory_hotplug.c  ⑨
  --> put_online_cpus()@kernel/cpu.c  ⑩

① cpu hotplugが管理している構造体のリファレンスカウンタを一つ増やす

② memory hotplugが管理している構造体のリファレンスカウンタを一つ増やす

③ kmem_cache_sanity_check()はデバッグ用の関数でCONFIG_DEBUG_VMがセットされていなければ何もしない

④ __kmem_cache_alias()は作成しようとしている大きさに合うスラブがあるか調べて、マージ可能であれば既存のキャッシュにエイリアスを振って作成しようとしていた名前でもアクセスできるようにする。ただし、通常はsetup_slub_nomerge()でマージ不可に設定している。

⑤ マージ可能なキャッシュを探すけど、④で書いたとおり通常はマージ可能なキャッシュはないはず

⑥ 新規にスラブキャッシュを作成するメインの関数

⑦ memcg用のデータを設定。内容としてはstrucdt kmem_cache構造体のmemcg_params変数のメモリ確保とmemcg_paramsのis_root_cacheをtrueに設定する

⑧ ここがスラフキャッシュ作成の本編でスラブアローケーター毎に実装がある。slubの場合はmm/slub.c。今日はここは読み飛ばして、次回ちゃんと読む

⑨ ②で増やした参照カウンタを減らす

⑩ ①で増やした参照カウンタを減らす